narray first check in
authorchris <none@none>
Mon, 27 Sep 1999 15:54:42 +0000 (15:54 +0000)
committerchris <none@none>
Mon, 27 Sep 1999 15:54:42 +0000 (15:54 +0000)
35 files changed:
Makefile [new file with mode: 0644]
Makefile.in
aclocal.m4
alpha/Makefile.in
alpha/ngen.c
comp/Makefile.in
config.h.in
configure
doc/array.tex [new file with mode: 0644]
global.h
jit.c
jit.h
jit/Makefile.in
jit/jitdef.h
jit/mcode.c
jit/parse.c
jit/reg.c
jit/stack.c
main.c
mips/Makefile.in
mm/Makefile.in
narray/analyze.c [new file with mode: 0644]
narray/graph.c [new file with mode: 0644]
narray/loop.c [new file with mode: 0644]
narray/loop.h [new file with mode: 0644]
narray/tracing.c [new file with mode: 0644]
nat/Makefile.in
src/cacao/cacao.c
src/vm/global.h
src/vm/jit/parse.c
src/vm/jit/stack.c
tests/Makefile.in
tests/jctest.java
threads/Makefile.in
toolbox/Makefile.in

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..b4bcb5b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,559 @@
+# Generated automatically from Makefile.in by configure.
+# Makefile.in generated automatically by automake 1.3 from Makefile.am
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id: Makefile 132 1999-09-27 15:54:42Z chris $
+
+
+SHELL = /bin/sh
+
+srcdir = .
+top_srcdir = .
+prefix = /usr/local/cacao
+exec_prefix = ${prefix}
+
+bindir = ${exec_prefix}/bin
+sbindir = ${exec_prefix}/sbin
+libexecdir = ${exec_prefix}/libexec
+datadir = ${prefix}/share
+sysconfdir = ${prefix}/etc
+sharedstatedir = ${prefix}/com
+localstatedir = ${prefix}/var
+libdir = ${exec_prefix}/lib
+infodir = ${prefix}/info
+mandir = ${prefix}/man
+includedir = ${prefix}/include
+oldincludedir = /usr/include
+
+DISTDIR =
+
+pkgdatadir = $(datadir)/cacao
+pkglibdir = $(libdir)/cacao
+pkgincludedir = $(includedir)/cacao
+
+top_builddir = .
+
+ACLOCAL = aclocal
+AUTOCONF = autoconf
+AUTOMAKE = automake
+AUTOHEADER = autoheader
+
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+transform = s,x,x,
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = alpha-unknown-linux
+host_triplet = alpha-unknown-linux-gnu
+CC = gcc
+COMPILER_OBJECTS = compiler.o
+COMPILER_SOURCES = compiler.h compiler.c
+GC_OBJ = mm/libmm_new.a
+LIBTHREAD = libthreads.a
+MAKEINFO = makeinfo
+PACKAGE = cacao
+RANLIB = ranlib
+SYSDEP_DIR = alpha
+THREAD_OBJ = threads/libthreads.a
+VERSION = 0.40
+
+MAINTAINERCLEANFILES = Makefile.in configure
+SUBDIRS = toolbox mm alpha jit comp nat threads mips tst doc narray
+
+EXTRA_DIST = html/cacaoinstall.html html/cacaoman.html html/index.html
+
+CLEANFILES = alpha/asmpart.o \
+                        alpha/asmpart.s \
+             alpha/offsets.h \
+                nativetable.hh \
+                nativetypes.hh
+
+bin_PROGRAMS = cacao
+noinst_PROGRAMS = cacaoh
+
+INCLUDES=-I/usr/include -I$(top_srcdir)/alpha -I$(top_srcdir)/jit -Ialpha -I$(top_srcdir)
+
+cacao_SOURCES = \
+       asmpart.h \
+       builtin.c \
+       builtin.h \
+       callargs.h \
+       compiler.h compiler.c \
+       global.h \
+       jit.c \
+       jit.h \
+       loader.c \
+       loader.h \
+       main.c \
+       native.c \
+       native.h \
+       tables.c \
+       tables.h 
+
+EXTRA_cacao_SOURCES = \
+       compiler.c \
+       compiler.h 
+
+cacao_LDADD = \
+       alpha/asmpart.o \
+       compiler.o \
+       toolbox/libtoolbox.a \
+       mm/libmm_new.a \
+    threads/libthreads.a
+
+cacao_DEPENDENCIES = \
+       alpha/asmpart.o \
+       compiler.o \
+       toolbox/libtoolbox.a \
+       mm/libmm_new.a \
+       threads/libthreads.a
+
+cacaoh_SOURCES = headers.c tables.c loader.c builtin.c
+cacaoh_LDADD = toolbox/libtoolbox.a mm/libmm_new.a threads/libthreads.a
+cacaoh_DEPENDENCIES = toolbox/libtoolbox.a mm/libmm_new.a threads/libthreads.a
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = 
+PROGRAMS =  $(bin_PROGRAMS) $(noinst_PROGRAMS)
+
+
+DEFS = -DHAVE_CONFIG_H -I. -I$(srcdir) -I.
+CPPFLAGS = 
+LDFLAGS = 
+LIBS = -lm 
+cacao_OBJECTS =  builtin.o jit.o loader.o main.o native.o tables.o
+cacao_LDFLAGS = 
+cacaoh_OBJECTS =  headers.o tables.o loader.o builtin.o
+cacaoh_LDFLAGS = 
+CFLAGS = -ieee -O2 -g3
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  README AUTHORS COPYING ChangeLog INSTALL Makefile.am \
+Makefile.in NEWS acconfig.h aclocal.m4 config.guess config.h.in \
+config.sub configure configure.in install-sh missing mkinstalldirs \
+stamp-h.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP = --best
+DEP_FILES =  .deps/builtin.P .deps/compiler.P .deps/headers.P \
+.deps/jit.P .deps/loader.P .deps/main.P .deps/native.P .deps/tables.P
+SOURCES = $(cacao_SOURCES) $(EXTRA_cacao_SOURCES) $(cacaoh_SOURCES)
+OBJECTS = $(cacao_OBJECTS) $(cacaoh_OBJECTS)
+
+all: all-recursive-am all-am
+
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+       cd $(top_builddir) \
+         && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4):  configure.in 
+       cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure
+       $(SHELL) ./config.status --recheck
+$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+       cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+       @:
+stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES= CONFIG_HEADERS=config.h \
+            $(SHELL) ./config.status
+       @echo timestamp > stamp-h
+$(srcdir)/config.h.in: $(srcdir)/stamp-h.in
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h
+       cd $(top_srcdir) && $(AUTOHEADER)
+       @echo timestamp > $(srcdir)/stamp-h.in
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+       -rm -f config.h
+
+maintainer-clean-hdr:
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+       -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(bindir)
+       @list='$(bin_PROGRAMS)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo "  $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \
+            $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+         else :; fi; \
+       done
+
+uninstall-binPROGRAMS:
+       @$(NORMAL_UNINSTALL)
+       list='$(bin_PROGRAMS)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+       done
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+       -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+cacao: $(cacao_OBJECTS) $(cacao_DEPENDENCIES)
+       @rm -f cacao
+       $(LINK) $(cacao_LDFLAGS) $(cacao_OBJECTS) $(cacao_LDADD) $(LIBS)
+
+cacaoh: $(cacaoh_OBJECTS) $(cacaoh_DEPENDENCIES)
+       @rm -f cacaoh
+       $(LINK) $(cacaoh_LDFLAGS) $(cacaoh_OBJECTS) $(cacaoh_LDADD) $(LIBS)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive  \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+       @set fnord $(MAKEFLAGS); amf=$$2; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         target=`echo $@ | sed s/-recursive//`; \
+         echo "Making $$target in $$subdir"; \
+         (cd $$subdir && $(MAKE) $$target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done && test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+       @set fnord $(MAKEFLAGS); amf=$$2; \
+       rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+         rev="$$subdir $$rev"; \
+       done; \
+       for subdir in $$rev; do \
+         target=`echo $@ | sed s/-recursive//`; \
+         echo "Making $$target in $$subdir"; \
+         (cd $$subdir && $(MAKE) $$target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done && test -z "$$fail"
+tags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         (cd $$subdir && $(MAKE) tags); \
+       done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+       done; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+       -rm -rf $(distdir)
+       GZIP=$(GZIP) $(TAR) zxf $(distdir).tar.gz
+       mkdir $(distdir)/=build
+       mkdir $(distdir)/=inst
+       dc_install_base=`cd $(distdir)/=inst && pwd`; \
+       cd $(distdir)/=build \
+         && ../configure --srcdir=.. --prefix=$$dc_install_base \
+         && $(MAKE) \
+         && $(MAKE) dvi \
+         && $(MAKE) check \
+         && $(MAKE) install \
+         && $(MAKE) installcheck \
+         && $(MAKE) dist
+       -rm -rf $(distdir)
+       @echo "========================"; \
+       echo "$(distdir).tar.gz is ready for distribution"; \
+       echo "========================"
+dist: distdir
+       -chmod -R a+r $(distdir)
+       GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir)
+       -rm -rf $(distdir)
+dist-all: distdir
+       -chmod -R a+r $(distdir)
+       GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir)
+       -rm -rf $(distdir)
+distdir: $(DISTFILES)
+       -rm -rf $(distdir)
+       mkdir $(distdir)
+       -chmod 777 $(distdir)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu Makefile
+       $(mkinstalldirs) $(distdir)/html
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         test -f $(distdir)/$$file \
+         || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+         || cp -p $$d/$$file $(distdir)/$$file; \
+       done
+       for subdir in $(SUBDIRS); do \
+         test -d $(distdir)/$$subdir \
+         || mkdir $(distdir)/$$subdir \
+         || exit 1; \
+         chmod 777 $(distdir)/$$subdir; \
+         (cd $$subdir && $(MAKE) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+           || exit 1; \
+       done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+
+maintainer-clean-depend:
+       -rm -rf .deps
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).P -c $<
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).p -c $<
+       @-sed -e 's/^\([^:]*\)\.o:/\1.lo \1.o:/' \
+         < .deps/$(*F).p > .deps/$(*F).P
+       @-rm -f .deps/$(*F).p
+info: info-recursive
+dvi: dvi-recursive
+check: all-am
+       $(MAKE) check-recursive
+installcheck: installcheck-recursive
+all-recursive-am: config.h
+       $(MAKE) all-recursive
+
+all-am: Makefile $(PROGRAMS) config.h
+
+install-exec-am: install-binPROGRAMS
+
+uninstall-am: uninstall-binPROGRAMS
+
+install-exec: install-exec-recursive install-exec-am
+       @$(NORMAL_INSTALL)
+
+install-data: install-data-recursive
+       @$(NORMAL_INSTALL)
+
+install: install-recursive install-exec-am
+       @:
+
+uninstall: uninstall-recursive uninstall-am
+
+install-strip:
+       $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
+installdirs: installdirs-recursive
+       $(mkinstalldirs)  $(DATADIR)$(bindir)
+
+
+mostlyclean-generic:
+       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -rm -f Makefile $(DISTCLEANFILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean-am:  mostlyclean-hdr mostlyclean-binPROGRAMS \
+               mostlyclean-noinstPROGRAMS mostlyclean-compile \
+               mostlyclean-tags mostlyclean-depend mostlyclean-generic
+
+clean-am:  clean-hdr clean-binPROGRAMS clean-noinstPROGRAMS \
+               clean-compile clean-tags clean-depend clean-generic \
+               mostlyclean-am
+
+distclean-am:  distclean-hdr distclean-binPROGRAMS \
+               distclean-noinstPROGRAMS distclean-compile \
+               distclean-tags distclean-depend distclean-generic \
+               clean-am
+
+maintainer-clean-am:  maintainer-clean-hdr maintainer-clean-binPROGRAMS \
+               maintainer-clean-noinstPROGRAMS \
+               maintainer-clean-compile maintainer-clean-tags \
+               maintainer-clean-depend maintainer-clean-generic \
+               distclean-am
+
+mostlyclean:  mostlyclean-recursive mostlyclean-am
+
+clean:  clean-recursive clean-am
+
+distclean:  distclean-recursive distclean-am
+       -rm -f config.status
+
+maintainer-clean:  maintainer-clean-recursive maintainer-clean-am
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+       -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile install-data-recursive \
+uninstall-data-recursive install-exec-recursive \
+uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
+all-recursive check-recursive installcheck-recursive info-recursive \
+dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info dvi installcheck all-recursive-am all-am \
+install-exec-am uninstall-am install-exec install-data install \
+uninstall all installdirs mostlyclean-generic distclean-generic \
+clean-generic maintainer-clean-generic clean mostlyclean distclean \
+maintainer-clean
+
+
+native.c: nativetypes.hh alpha/offsets.h nativetable.hh
+
+nativetypes.hh alpha/offsets.h nativetable.hh: cacaoh
+       ./cacaoh \
+               java.lang.Object \
+               java.lang.String \
+               java.lang.Class \
+               java.lang.ClassLoader \
+               java.lang.Compiler \
+               java.lang.Double \
+               java.lang.Float \
+               java.lang.Math \
+               java.lang.Runtime \
+               java.lang.SecurityManager \
+               java.lang.System \
+               java.lang.Thread \
+               java.lang.ThreadGroup \
+               java.lang.Throwable \
+               java.io.File \
+               java.io.FileDescriptor \
+               java.io.FileInputStream \
+               java.io.FileOutputStream \
+               java.io.PrintStream \
+               java.io.RandomAccessFile \
+               java.util.Properties \
+               java.util.Date
+
+alpha/asmpart.o: $(top_srcdir)/alpha/asmpart.c alpha/offsets.h
+       rm -f alpha/asmpart.s
+       gcc -E $(INCLUDES) $(top_srcdir)/alpha/asmpart.c \
+                       > alpha/asmpart.s
+       gcc $(CFLAGS) $(INCLUDES) -c -o alpha/asmpart.o \
+                       alpha/asmpart.s
+       rm -f asmpart.s
+
+compiler.o: $(top_srcdir)/builtin.h $(top_srcdir)/compiler.h \
+                   $(top_srcdir)/global.h $(top_srcdir)/loader.h \
+               $(top_srcdir)/tables.h $(top_srcdir)/native.h \
+            $(top_srcdir)/asmpart.h $(top_srcdir)/compiler.c $(top_srcdir)/comp/*.c \
+            $(top_srcdir)/alpha/gen.c $(top_srcdir)/alpha/disass.c
+       gcc $(CFLAGS) -I. $(INCLUDES) -c $(top_srcdir)/compiler.c
+
+jit.o: jit.c \
+       jit/mcode.c \
+       jit/parse.c \
+       jit/reg.c \
+       jit/stack.c \
+       jit/jitdef.h \
+       narray/graph.c \
+       narray/loop.c \
+       narray/analyze.c \
+       narray/tracing.c \
+       narray/loop.h
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
index 81eaabe24d0b10f4bc5f1cfaf53107a01a8e91fc..38aaff47abb58d5f8220188f379ca1dde9027052 100644 (file)
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4 from Makefile.am
+# Makefile.in generated automatically by automake 1.3 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.
 
-# $Id: Makefile.in 128 1999-03-03 15:54:06Z phil $
+# $Id: Makefile.in 132 1999-09-27 15:54:42Z chris $
 
 
-SHELL = @SHELL@
+SHELL = /bin/sh
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -34,7 +34,7 @@ mandir = @mandir@
 includedir = @includedir@
 oldincludedir = /usr/include
 
-DESTDIR =
+DISTDIR =
 
 pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -48,7 +48,7 @@ AUTOMAKE = @AUTOMAKE@
 AUTOHEADER = @AUTOHEADER@
 
 INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 transform = @program_transform_name@
@@ -74,15 +74,22 @@ THREAD_OBJ = @THREAD_OBJ@
 VERSION = @VERSION@
 
 MAINTAINERCLEANFILES = Makefile.in configure
-SUBDIRS = toolbox mm alpha jit comp nat threads mips tst doc
+SUBDIRS = toolbox mm alpha jit comp nat threads mips tst doc narray
 
 EXTRA_DIST = html/cacaoinstall.html html/cacaoman.html html/index.html
 
-CLEANFILES = @SYSDEP_DIR@/asmpart.o                     @SYSDEP_DIR@/asmpart.s              @SYSDEP_DIR@/offsets.h              nativetable.hh                  nativetypes.hh
-
+CLEANFILES = @SYSDEP_DIR@/asmpart.o \
+                        @SYSDEP_DIR@/asmpart.s \
+             @SYSDEP_DIR@/offsets.h \
+                nativetable.hh \
+                nativetypes.hh
 
 bin_PROGRAMS = cacao
 noinst_PROGRAMS = cacaoh
+<<<<<<< Makefile.in
+
+INCLUDES=-I/usr/include -I$(top_srcdir)/@SYSDEP_DIR@ -I$(top_srcdir)/jit -I@SYSDEP_DIR@ -I$(top_srcdir)
+=======
 
 INCLUDES = -I/usr/include -I$(top_srcdir)/@SYSDEP_DIR@ -I$(top_srcdir)/jit -I@SYSDEP_DIR@ -I$(top_srcdir)
 
@@ -93,10 +100,42 @@ EXTRA_cacao_SOURCES =      compiler.c      compiler.h
 
 
 cacao_LDADD =          @SYSDEP_DIR@/asmpart.o  @COMPILER_OBJECTS@      toolbox/libtoolbox.a    @GC_OBJ@     @THREAD_OBJ@
-
-
-cacao_DEPENDENCIES =   @SYSDEP_DIR@/asmpart.o  @COMPILER_OBJECTS@      toolbox/libtoolbox.a    @GC_OBJ@        @THREAD_OBJ@
-
+>>>>>>> 3.10
+
+cacao_SOURCES = \
+       asmpart.h \
+       builtin.c \
+       builtin.h \
+       callargs.h \
+       @COMPILER_SOURCES@ \
+       global.h \
+       jit.c \
+       jit.h \
+       loader.c \
+       loader.h \
+       main.c \
+       native.c \
+       native.h \
+       tables.c \
+       tables.h 
+
+EXTRA_cacao_SOURCES = \
+       compiler.c \
+       compiler.h 
+
+cacao_LDADD = \
+       @SYSDEP_DIR@/asmpart.o \
+       @COMPILER_OBJECTS@ \
+       toolbox/libtoolbox.a \
+       @GC_OBJ@ \
+    @THREAD_OBJ@
+
+cacao_DEPENDENCIES = \
+       @SYSDEP_DIR@/asmpart.o \
+       @COMPILER_OBJECTS@ \
+       toolbox/libtoolbox.a \
+       @GC_OBJ@ \
+       @THREAD_OBJ@
 
 cacaoh_SOURCES = headers.c tables.c loader.c builtin.c
 cacaoh_LDADD = toolbox/libtoolbox.a @GC_OBJ@ @THREAD_OBJ@
@@ -117,58 +156,53 @@ cacao_LDFLAGS =
 cacaoh_OBJECTS =  headers.o tables.o loader.o builtin.o
 cacaoh_LDFLAGS = 
 CFLAGS = @CFLAGS@
-COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
-DIST_COMMON =  README ./stamp-h.in AUTHORS COPYING ChangeLog INSTALL \
-Makefile.am Makefile.in NEWS acconfig.h aclocal.m4 config.guess \
-config.h.in config.sub configure configure.in install-sh missing \
-mkinstalldirs
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  README AUTHORS COPYING ChangeLog INSTALL Makefile.am \
+Makefile.in NEWS acconfig.h aclocal.m4 config.guess config.h.in \
+config.sub configure configure.in install-sh missing mkinstalldirs \
+stamp-h.in
 
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = tar
-GZIP_ENV = --best
+GZIP = --best
+DEP_FILES =  .deps/builtin.P .deps/compiler.P .deps/headers.P \
+.deps/jit.P .deps/loader.P .deps/main.P .deps/native.P .deps/tables.P
 SOURCES = $(cacao_SOURCES) $(EXTRA_cacao_SOURCES) $(cacaoh_SOURCES)
 OBJECTS = $(cacao_OBJECTS) $(cacaoh_OBJECTS)
 
-all: all-redirect
+all: all-recursive-am all-am
+
 .SUFFIXES:
 .SUFFIXES: .S .c .o .s
-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-       cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
 $(ACLOCAL_M4):  configure.in 
        cd $(srcdir) && $(ACLOCAL)
 
-config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+config.status: $(srcdir)/configure
        $(SHELL) ./config.status --recheck
 $(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
        cd $(srcdir) && $(AUTOCONF)
 
 config.h: stamp-h
-       @if test ! -f $@; then \
-               rm -f stamp-h; \
-               $(MAKE) stamp-h; \
-       else :; fi
+       @:
 stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
        cd $(top_builddir) \
          && CONFIG_FILES= CONFIG_HEADERS=config.h \
             $(SHELL) ./config.status
-       @echo timestamp > stamp-h 2> /dev/null
+       @echo timestamp > stamp-h
 $(srcdir)/config.h.in: $(srcdir)/stamp-h.in
-       @if test ! -f $@; then \
-               rm -f $(srcdir)/stamp-h.in; \
-               $(MAKE) $(srcdir)/stamp-h.in; \
-       else :; fi
 $(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h
        cd $(top_srcdir) && $(AUTOHEADER)
-       @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+       @echo timestamp > $(srcdir)/stamp-h.in
 
 mostlyclean-hdr:
 
@@ -193,15 +227,15 @@ install-binPROGRAMS: $(bin_PROGRAMS)
        $(mkinstalldirs) $(DESTDIR)$(bindir)
        @list='$(bin_PROGRAMS)'; for p in $$list; do \
          if test -f $$p; then \
-           echo "  $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
-            $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+           echo "  $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \
+            $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
          else :; fi; \
        done
 
 uninstall-binPROGRAMS:
        @$(NORMAL_UNINSTALL)
        list='$(bin_PROGRAMS)'; for p in $$list; do \
-         rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+         rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
        done
 
 mostlyclean-noinstPROGRAMS:
@@ -213,9 +247,6 @@ distclean-noinstPROGRAMS:
 
 maintainer-clean-noinstPROGRAMS:
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -253,65 +284,41 @@ all-recursive install-data-recursive install-exec-recursive \
 installdirs-recursive install-recursive uninstall-recursive  \
 check-recursive installcheck-recursive info-recursive dvi-recursive:
        @set fnord $(MAKEFLAGS); amf=$$2; \
-       dot_seen=no; \
-       target=`echo $@ | sed s/-recursive//`; \
        list='$(SUBDIRS)'; for subdir in $$list; do \
+         target=`echo $@ | sed s/-recursive//`; \
          echo "Making $$target in $$subdir"; \
-         if test "$$subdir" = "."; then \
-           dot_seen=yes; \
-           local_target="$$target-am"; \
-         else \
-           local_target="$$target"; \
-         fi; \
-         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+         (cd $$subdir && $(MAKE) $$target) \
           || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
-       done; \
-       if test "$$dot_seen" = "no"; then \
-         $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
-       fi; test -z "$$fail"
+       done && test -z "$$fail"
 
 mostlyclean-recursive clean-recursive distclean-recursive \
 maintainer-clean-recursive:
        @set fnord $(MAKEFLAGS); amf=$$2; \
-       dot_seen=no; \
        rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
          rev="$$subdir $$rev"; \
-         test "$$subdir" = "." && dot_seen=yes; \
        done; \
-       test "$$dot_seen" = "no" && rev=". $$rev"; \
-       target=`echo $@ | sed s/-recursive//`; \
        for subdir in $$rev; do \
+         target=`echo $@ | sed s/-recursive//`; \
          echo "Making $$target in $$subdir"; \
-         if test "$$subdir" = "."; then \
-           local_target="$$target-am"; \
-         else \
-           local_target="$$target"; \
-         fi; \
-         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+         (cd $$subdir && $(MAKE) $$target) \
           || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
        done && test -z "$$fail"
 tags-recursive:
        list='$(SUBDIRS)'; for subdir in $$list; do \
-         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+         (cd $$subdir && $(MAKE) tags); \
        done
 
 tags: TAGS
 
 ID: $(HEADERS) $(SOURCES) $(LISP)
-       list='$(SOURCES) $(HEADERS)'; \
-       unique=`for i in $$list; do echo $$i; done | \
-         awk '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
        here=`pwd` && cd $(srcdir) \
-         && mkid -f$$here/ID $$unique $(LISP)
+         && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
 
 TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP)
        tags=; \
        here=`pwd`; \
        list='$(SUBDIRS)'; for subdir in $$list; do \
-   if test "$$subdir" = .; then :; else \
-           test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
-   fi; \
+         test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
        done; \
        list='$(SOURCES) $(HEADERS)'; \
        unique=`for i in $$list; do echo $$i; done | \
@@ -337,125 +344,152 @@ top_distdir = $(distdir)
 # tarfile.
 distcheck: dist
        -rm -rf $(distdir)
-       GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+       GZIP=$(GZIP) $(TAR) zxf $(distdir).tar.gz
        mkdir $(distdir)/=build
        mkdir $(distdir)/=inst
        dc_install_base=`cd $(distdir)/=inst && pwd`; \
        cd $(distdir)/=build \
          && ../configure --srcdir=.. --prefix=$$dc_install_base \
-         && $(MAKE) $(AM_MAKEFLAGS) \
-         && $(MAKE) $(AM_MAKEFLAGS) dvi \
-         && $(MAKE) $(AM_MAKEFLAGS) check \
-         && $(MAKE) $(AM_MAKEFLAGS) install \
-         && $(MAKE) $(AM_MAKEFLAGS) installcheck \
-         && $(MAKE) $(AM_MAKEFLAGS) dist
+         && $(MAKE) \
+         && $(MAKE) dvi \
+         && $(MAKE) check \
+         && $(MAKE) install \
+         && $(MAKE) installcheck \
+         && $(MAKE) dist
        -rm -rf $(distdir)
-       @banner="$(distdir).tar.gz is ready for distribution"; \
-       dashes=`echo "$$banner" | sed s/./=/g`; \
-       echo "$$dashes"; \
-       echo "$$banner"; \
-       echo "$$dashes"
+       @echo "========================"; \
+       echo "$(distdir).tar.gz is ready for distribution"; \
+       echo "========================"
 dist: distdir
        -chmod -R a+r $(distdir)
-       GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+       GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir)
        -rm -rf $(distdir)
 dist-all: distdir
        -chmod -R a+r $(distdir)
-       GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+       GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir)
        -rm -rf $(distdir)
 distdir: $(DISTFILES)
        -rm -rf $(distdir)
        mkdir $(distdir)
        -chmod 777 $(distdir)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu Makefile
        $(mkinstalldirs) $(distdir)/html
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
-         if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
-         else \
-           test -f $(distdir)/$$file \
-           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
-           || cp -p $$d/$$file $(distdir)/$$file || :; \
-         fi; \
+         test -f $(distdir)/$$file \
+         || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+         || cp -p $$d/$$file $(distdir)/$$file; \
        done
        for subdir in $(SUBDIRS); do \
-         if test "$$subdir" = .; then :; else \
-           test -d $(distdir)/$$subdir \
-           || mkdir $(distdir)/$$subdir \
+         test -d $(distdir)/$$subdir \
+         || mkdir $(distdir)/$$subdir \
+         || exit 1; \
+         chmod 777 $(distdir)/$$subdir; \
+         (cd $$subdir && $(MAKE) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
            || exit 1; \
-           chmod 777 $(distdir)/$$subdir; \
-           (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
-             || exit 1; \
-         fi; \
        done
-info-am:
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+
+maintainer-clean-depend:
+       -rm -rf .deps
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).P -c $<
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).p -c $<
+       @-sed -e 's/^\([^:]*\)\.o:/\1.lo \1.o:/' \
+         < .deps/$(*F).p > .deps/$(*F).P
+       @-rm -f .deps/$(*F).p
 info: info-recursive
-dvi-am:
 dvi: dvi-recursive
-check-am: all-am
-check: check-recursive
-installcheck-am:
+check: all-am
+       $(MAKE) check-recursive
 installcheck: installcheck-recursive
 all-recursive-am: config.h
-       $(MAKE) $(AM_MAKEFLAGS) all-recursive
+       $(MAKE) all-recursive
+
+all-am: Makefile $(PROGRAMS) config.h
 
 install-exec-am: install-binPROGRAMS
-install-exec: install-exec-recursive
 
-install-data-am:
+uninstall-am: uninstall-binPROGRAMS
+
+install-exec: install-exec-recursive install-exec-am
+       @$(NORMAL_INSTALL)
+
 install-data: install-data-recursive
+       @$(NORMAL_INSTALL)
+
+install: install-recursive install-exec-am
+       @:
+
+uninstall: uninstall-recursive uninstall-am
 
-install-am: all-am
-       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-install: install-recursive
-uninstall-am: uninstall-binPROGRAMS
-uninstall: uninstall-recursive
-all-am: Makefile $(PROGRAMS) config.h
-all-redirect: all-recursive-am
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+       $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
 installdirs: installdirs-recursive
-installdirs-am:
-       $(mkinstalldirs)  $(DESTDIR)$(bindir)
+       $(mkinstalldirs)  $(DATADIR)$(bindir)
 
 
 mostlyclean-generic:
+       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
 
 clean-generic:
        -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
-       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f Makefile $(DISTCLEANFILES)
        -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
 
 maintainer-clean-generic:
        -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
 mostlyclean-am:  mostlyclean-hdr mostlyclean-binPROGRAMS \
                mostlyclean-noinstPROGRAMS mostlyclean-compile \
-               mostlyclean-tags mostlyclean-generic
-
-mostlyclean: mostlyclean-recursive
+               mostlyclean-tags mostlyclean-depend mostlyclean-generic
 
 clean-am:  clean-hdr clean-binPROGRAMS clean-noinstPROGRAMS \
-               clean-compile clean-tags clean-generic mostlyclean-am
-
-clean: clean-recursive
+               clean-compile clean-tags clean-depend clean-generic \
+               mostlyclean-am
 
 distclean-am:  distclean-hdr distclean-binPROGRAMS \
                distclean-noinstPROGRAMS distclean-compile \
-               distclean-tags distclean-generic clean-am
-
-distclean: distclean-recursive
-       -rm -f config.status
+               distclean-tags distclean-depend distclean-generic \
+               clean-am
 
 maintainer-clean-am:  maintainer-clean-hdr maintainer-clean-binPROGRAMS \
                maintainer-clean-noinstPROGRAMS \
                maintainer-clean-compile maintainer-clean-tags \
-               maintainer-clean-generic distclean-am
+               maintainer-clean-depend maintainer-clean-generic \
+               distclean-am
+
+mostlyclean:  mostlyclean-recursive mostlyclean-am
+
+clean:  clean-recursive clean-am
+
+distclean:  distclean-recursive distclean-am
+       -rm -f config.status
+
+maintainer-clean:  maintainer-clean-recursive maintainer-clean-am
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
-
-maintainer-clean: maintainer-clean-recursive
        -rm -f config.status
 
 .PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
@@ -470,12 +504,13 @@ uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
 all-recursive check-recursive installcheck-recursive info-recursive \
 dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
 maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
-distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
-dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs-am \
-installdirs mostlyclean-generic distclean-generic clean-generic \
-maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info dvi installcheck all-recursive-am all-am \
+install-exec-am uninstall-am install-exec install-data install \
+uninstall all installdirs mostlyclean-generic distclean-generic \
+clean-generic maintainer-clean-generic clean mostlyclean distclean \
+maintainer-clean
 
 
 native.c: nativetypes.hh @SYSDEP_DIR@/offsets.h nativetable.hh
@@ -513,11 +548,27 @@ nativetypes.hh @SYSDEP_DIR@/offsets.h nativetable.hh: cacaoh
                        @SYSDEP_DIR@/asmpart.s
        rm -f asmpart.s
 
-compiler.o: builtin.h compiler.h global.h loader.h tables.h native.h \
-            asmpart.h compiler.c comp/*.c \
-            @SYSDEP_DIR@/gen.c @SYSDEP_DIR@/disass.c
-       @CC@ $(CFLAGS) $(INCLUDES) -c compiler.c
+compiler.o: $(top_srcdir)/builtin.h $(top_srcdir)/compiler.h \
+                   $(top_srcdir)/global.h $(top_srcdir)/loader.h \
+               $(top_srcdir)/tables.h $(top_srcdir)/native.h \
+            $(top_srcdir)/asmpart.h $(top_srcdir)/compiler.c $(top_srcdir)/comp/*.c \
+            $(top_srcdir)/@SYSDEP_DIR@/gen.c $(top_srcdir)/@SYSDEP_DIR@/disass.c
+       @CC@ $(CFLAGS) -I. $(INCLUDES) -c $(top_srcdir)/compiler.c
 
+<<<<<<< Makefile.in
+jit.o: jit.c \
+       jit/mcode.c \
+       jit/parse.c \
+       jit/reg.c \
+       jit/stack.c \
+       jit/jitdef.h \
+       narray/graph.c \
+       narray/loop.c \
+       narray/analyze.c \
+       narray/tracing.c \
+       narray/loop.h
+
+=======
 jit.o: jit.c \
        jit/mcode.c \
        jit/parse.c \
@@ -525,6 +576,7 @@ jit.o: jit.c \
        jit/stack.c \
        jit/jitdef.h
 
+>>>>>>> 3.10
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
index f23ba2904e17f5ce128893301a5f29aad9149aeb..0520b196d725e0209fcf56c4a787f11fd8cd9986 100644 (file)
@@ -1,7 +1,7 @@
-dnl aclocal.m4 generated automatically by aclocal 1.4
+dnl aclocal.m4 generated automatically by aclocal 1.3
 
-dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
+dnl Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+dnl This Makefile.in is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 
@@ -20,7 +20,7 @@ dnl Usage:
 dnl AM_INIT_AUTOMAKE(package,version, [no-define])
 
 AC_DEFUN(AM_INIT_AUTOMAKE,
-[AC_REQUIRE([AC_PROG_INSTALL])
+[AC_REQUIRE([AM_PROG_INSTALL])
 PACKAGE=[$1]
 AC_SUBST(PACKAGE)
 VERSION=[$2]
@@ -30,8 +30,8 @@ if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
   AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
 fi
 ifelse([$3],,
-AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
-AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION"))
 AC_REQUIRE([AM_SANITY_CHECK])
 AC_REQUIRE([AC_ARG_PROGRAM])
 dnl FIXME This is truly gross.
@@ -43,6 +43,15 @@ AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
 AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
 AC_REQUIRE([AC_PROG_MAKE_SET])])
 
+
+# serial 1
+
+AC_DEFUN(AM_PROG_INSTALL,
+[AC_REQUIRE([AC_PROG_INSTALL])
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+AC_SUBST(INSTALL_SCRIPT)dnl
+])
+
 #
 # Check to make sure that the build environment is sane.
 #
index 9862c42228e0cdf759964a3f81222d2e4d732c6d..d9d7b72dce4fad8b6bcc0cc7ce5e5d2567708d48 100644 (file)
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4 from Makefile.am
+# Makefile.in generated automatically by automake 1.3 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -11,7 +11,7 @@
 # PARTICULAR PURPOSE.
 
 
-SHELL = @SHELL@
+SHELL = /bin/sh
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -32,7 +32,7 @@ mandir = @mandir@
 includedir = @includedir@
 oldincludedir = /usr/include
 
-DESTDIR =
+DISTDIR =
 
 pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -46,7 +46,7 @@ AUTOMAKE = @AUTOMAKE@
 AUTOHEADER = @AUTOHEADER@
 
 INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 transform = @program_transform_name@
@@ -71,8 +71,9 @@ SYSDEP_DIR = @SYSDEP_DIR@
 THREAD_OBJ = @THREAD_OBJ@
 VERSION = @VERSION@
 
-EXTRA_DIST = asmpart.c disass.c cray.c gen.c ngen.c         defines.h native-math.h ngen.h sigcontext.h             types.h threads.h 
-
+EXTRA_DIST = asmpart.c disass.c cray.c gen.c ngen.c \
+            defines.h native-math.h ngen.h sigcontext.h \
+            types.h threads.h 
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = ../config.h
 CONFIG_CLEAN_FILES = 
@@ -82,13 +83,14 @@ DIST_COMMON =  Makefile.am Makefile.in
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = tar
-GZIP_ENV = --best
-all: all-redirect
+GZIP = --best
+all: Makefile
+
 .SUFFIXES:
-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-       cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps alpha/Makefile
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu alpha/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -101,75 +103,67 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = alpha
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu alpha/Makefile
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
-         if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
-         else \
-           test -f $(distdir)/$$file \
-           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
-           || cp -p $$d/$$file $(distdir)/$$file || :; \
-         fi; \
+         test -f $(distdir)/$$file \
+         || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+         || cp -p $$d/$$file $(distdir)/$$file; \
        done
-info-am:
-info: info-am
-dvi-am:
-dvi: dvi-am
-check-am: all-am
-check: check-am
-installcheck-am:
-installcheck: installcheck-am
-install-exec-am:
-install-exec: install-exec-am
-
-install-data-am:
-install-data: install-data-am
-
-install-am: all-am
-       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-install: install-am
-uninstall-am:
-uninstall: uninstall-am
-all-am: Makefile
-all-redirect: all-am
+info:
+dvi:
+check: all
+       $(MAKE)
+installcheck:
+install-exec: 
+       @$(NORMAL_INSTALL)
+
+install-data: 
+       @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+       @:
+
+uninstall: 
+
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+       $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
 installdirs:
 
 
 mostlyclean-generic:
+       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
 
 clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
-       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f Makefile $(DISTCLEANFILES)
        -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
 
 maintainer-clean-generic:
-mostlyclean-am:  mostlyclean-generic
-
-mostlyclean: mostlyclean-am
-
-clean-am:  clean-generic mostlyclean-am
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean:  mostlyclean-generic
 
-clean: clean-am
+clean:  clean-generic mostlyclean
 
-distclean-am:  distclean-generic clean-am
+distclean:  distclean-generic clean
+       -rm -f config.status
 
-distclean: distclean-am
-
-maintainer-clean-am:  maintainer-clean-generic distclean-am
+maintainer-clean:  maintainer-clean-generic distclean
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
-maintainer-clean: maintainer-clean-am
-
-.PHONY: tags distdir info-am info dvi-am dvi check check-am \
-installcheck-am installcheck install-exec-am install-exec \
-install-data-am install-data install-am install uninstall-am uninstall \
-all-redirect all-am all installdirs mostlyclean-generic \
-distclean-generic clean-generic maintainer-clean-generic clean \
-mostlyclean distclean maintainer-clean
+.PHONY: tags distdir info dvi installcheck install-exec install-data \
+install uninstall all installdirs mostlyclean-generic distclean-generic \
+clean-generic maintainer-clean-generic clean mostlyclean distclean \
+maintainer-clean
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
index bd6d78252523d4872f1bdd0c14b0855f98b3c352..69771a08159665e56a6f9889cef324d7965b679d 100644 (file)
@@ -11,7 +11,7 @@
        Authors: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
                 Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
 
-       Last Change: $Id: ngen.c 115 1999-01-20 01:52:45Z phil $
+       Last Change: $Id: ngen.c 132 1999-09-27 15:54:42Z chris $
 
 *******************************************************************************/
 
@@ -45,7 +45,9 @@ in the documention file: calling.doc
 
 /* additional functions and macros to generate code ***************************/
 
-#define BlockPtrOfPC(pc)        block+block_index[pc]
+/* #define BlockPtrOfPC(pc)        block+block_index[pc] */
+#define BlockPtrOfPC(pc)  ((basicblock *) iptr->target)
+
 
 #ifdef STATISTICS
 #define COUNT_SPILLS count_spills++
@@ -326,6 +328,7 @@ static void gen_mcode()
        varinfo     *var;
        basicblock  *bptr;
        instruction *iptr;
+       xtable *ex;
 
        {
        int p, pa, t, l, r;
@@ -373,14 +376,45 @@ static void gen_mcode()
        (void) dseg_adds4(exceptiontablelength);                /* ExTableSize    */
 
        /* create exception table */
-       
-       for (len = 0; len < exceptiontablelength; len++) {
-               dseg_addtarget(BlockPtrOfPC(extable[len].startpc));
-               dseg_addtarget(BlockPtrOfPC(extable[len].endpc));
-               dseg_addtarget(BlockPtrOfPC(extable[len].handlerpc));
-               (void) dseg_addaddress(extable[len].catchtype);
+
+       for (ex = extable; ex != NULL; ex = ex->down) {
+
+#ifdef LOOP_DEBUG      
+               if (ex->start != NULL)
+                       printf("adding start - %d - ", ex->start->debug_nr);
+               else {
+                       printf("PANIC - start is NULL");
+                       exit(-1);
                }
+#endif
+
+               dseg_addtarget(ex->start);
+
+#ifdef LOOP_DEBUG                      
+               if (ex->end != NULL)
+                       printf("adding end - %d - ", ex->end->debug_nr);
+               else {
+                       printf("PANIC - end is NULL");
+                       exit(-1);
+               }
+#endif
 
+               dseg_addtarget(ex->end);
+
+#ifdef LOOP_DEBUG              
+               if (ex->handler != NULL)
+                       printf("adding handler - %d\n", ex->handler->debug_nr);
+               else {
+                       printf("PANIC - handler is NULL");
+                       exit(-1);
+               }
+#endif
+
+               dseg_addtarget(ex->handler);
+          
+               (void) dseg_addaddress(ex->catchtype);
+               }
+       
        /* initialize mcode variables */
        
        mcodeptr = (s4*) mcodebase;
@@ -542,8 +576,8 @@ static void gen_mcode()
        /* end of header generation */
 
        /* walk through all basic blocks */
+       for (/* bbs = block_count, */ bptr = block; /* --bbs >= 0 */ bptr != NULL; bptr = bptr->next) {
 
-       for (bbs = block_count, bptr = block; --bbs >= 0; bptr++) {
                bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
 
                if (bptr->flags >= BBREACHED) {
@@ -600,7 +634,7 @@ static void gen_mcode()
                        }
 
                /* walk through all instructions */
-
+               
                src = bptr->instack;
                len = bptr->icount;
                for (iptr = bptr->iinstr;
@@ -1848,13 +1882,22 @@ static void gen_mcode()
 
                /* memory operations **************************************************/
 
-#define gen_bound_check \
+                       /* #define gen_bound_check \
                        if (checkbounds) {\
                                M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
                                M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
                                M_BEQZ(REG_ITMP3, 0);\
                                mcode_addxboundrefs(mcodeptr);\
                                }
+                       */
+
+#define gen_bound_check \
+            if (checkbounds) { \
+                               M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));\
+                               M_CMPULT(s2, REG_ITMP3, REG_ITMP3);\
+                               M_BEQZ(REG_ITMP3, 0);\
+                               mcode_addxboundrefs(mcodeptr); \
+                }
 
                case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
 
@@ -1902,6 +1945,7 @@ static void gen_mcode()
                                gen_nullptr_check(s1);
                                gen_bound_check;
                                }
+                 
                        M_S4ADDQ(s2, s1, REG_ITMP1);
                        M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
                        store_reg_to_var_int(iptr->dst, d);
@@ -2044,6 +2088,7 @@ static void gen_mcode()
                                gen_nullptr_check(s1);
                                gen_bound_check;
                                }
+
                        var_to_reg_int(s3, src, REG_ITMP3);
                        M_S4ADDQ(s2, s1, REG_ITMP1);
                        M_IST   (s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
@@ -2972,6 +3017,9 @@ nowperformreturn:
                case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
                        {
                        s4 i, l, *s4ptr;
+                       void **tptr;
+
+                       tptr = (void **) iptr->target;
 
                        s4ptr = iptr->val.a;
                        l = s4ptr[1];                          /* low     */
@@ -2998,13 +3046,20 @@ nowperformreturn:
                                M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
                                }
                        M_BEQZ(REG_ITMP2, 0);
-                       mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr);
+
+
+                       /* mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
+                       mcode_addreference((basicblock *) tptr[0], mcodeptr);
 
                        /* build jump table top down and use address of lowest entry */
 
-                       s4ptr += 3 + i;
+                       /* s4ptr += 3 + i; */
+                       tptr += i;
+
                        while (--i >= 0) {
-                               dseg_addtarget(BlockPtrOfPC(*--s4ptr));
+                               /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
+                               dseg_addtarget((basicblock *) tptr[0]); 
+                               --tptr;
                                }
                        }
 
@@ -3020,6 +3075,9 @@ nowperformreturn:
                case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
                        {
                        s4 i, l, val, *s4ptr;
+                       void **tptr;
+
+                       tptr = (void **) iptr->target;
 
                        s4ptr = iptr->val.a;
                        l = s4ptr[0];                          /* default  */
@@ -3029,6 +3087,8 @@ nowperformreturn:
                        var_to_reg_int(s1, src, REG_ITMP1);
                        while (--i >= 0) {
                                s4ptr += 2;
+                               ++tptr;
+
                                val = s4ptr[0];
                                if ((val >= 0) && (val <= 255)) {
                                        M_CMPEQ_IMM(s1, val, REG_ITMP2);
@@ -3044,11 +3104,16 @@ nowperformreturn:
                                        M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
                                        }
                                M_BNEZ(REG_ITMP2, 0);
-                               mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr);
+                               /* mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
+                               mcode_addreference((basicblock *) tptr[0], mcodeptr); 
                                }
 
                        M_BR(0);
-                       mcode_addreference(BlockPtrOfPC(l), mcodeptr);
+                       /* mcode_addreference(BlockPtrOfPC(l), mcodeptr); */
+                       
+                       tptr = (void **) iptr->target;
+                       mcode_addreference((basicblock *) tptr[0], mcodeptr);
+
                        ALIGNCODENOP;
                        break;
                        }
@@ -3377,7 +3442,7 @@ makeactualcall:
                                while (ml < -32768) {ml += 65536; mh--;}
                                M_LDA(REG_PV, REG_RA, ml);
                                M_LDAH(REG_PV, REG_PV, mh);
-                               }
+                           }
                        s1 = reg_of_var(iptr->dst, REG_RESULT);
                        M_INTMOVE(REG_RESULT, s1);
                        store_reg_to_var_int(iptr->dst, s1);
@@ -3386,9 +3451,13 @@ makeactualcall:
 
                default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
                         error();
+       
+   
+
        } /* switch */
+               
        } /* for instruction */
-
+               
        /* copy values to interface registers */
 
        src = bptr->outstack;
@@ -3422,7 +3491,7 @@ makeactualcall:
        } /* if (bptr -> flags >= BBREACHED) */
        } /* for basic block */
 
-       bptr -> mpc = (int)((u1*) mcodeptr - mcodebase);
+       /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
 
        {
        /* generate bound check stubs */
@@ -3436,6 +3505,7 @@ makeactualcall:
                        continue;
                        }
 
+
                gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos, 
                                  xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
 
index 66c7a976e707bd0dd69749a6de8042fd1916dbd8..f238e75dda8531bdde0ea9c5fad21a0ace8deb31 100644 (file)
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4 from Makefile.am
+# Makefile.in generated automatically by automake 1.3 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -11,7 +11,7 @@
 # PARTICULAR PURPOSE.
 
 
-SHELL = @SHELL@
+SHELL = /bin/sh
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -32,7 +32,7 @@ mandir = @mandir@
 includedir = @includedir@
 oldincludedir = /usr/include
 
-DESTDIR =
+DISTDIR =
 
 pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -46,7 +46,7 @@ AUTOMAKE = @AUTOMAKE@
 AUTOHEADER = @AUTOHEADER@
 
 INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 transform = @program_transform_name@
@@ -71,8 +71,8 @@ SYSDEP_DIR = @SYSDEP_DIR@
 THREAD_OBJ = @THREAD_OBJ@
 VERSION = @VERSION@
 
-EXTRA_DIST = block.c local.c parse.c reg.c stack.c var.c            defines.c mcode.c pcmd.c regalloc.c tools.c
-
+EXTRA_DIST = block.c local.c parse.c reg.c stack.c var.c \
+            defines.c mcode.c pcmd.c regalloc.c tools.c
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = ../config.h
 CONFIG_CLEAN_FILES = 
@@ -82,13 +82,14 @@ DIST_COMMON =  Makefile.am Makefile.in
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = tar
-GZIP_ENV = --best
-all: all-redirect
+GZIP = --best
+all: Makefile
+
 .SUFFIXES:
-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-       cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps comp/Makefile
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu comp/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -101,75 +102,67 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = comp
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu comp/Makefile
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
-         if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
-         else \
-           test -f $(distdir)/$$file \
-           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
-           || cp -p $$d/$$file $(distdir)/$$file || :; \
-         fi; \
+         test -f $(distdir)/$$file \
+         || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+         || cp -p $$d/$$file $(distdir)/$$file; \
        done
-info-am:
-info: info-am
-dvi-am:
-dvi: dvi-am
-check-am: all-am
-check: check-am
-installcheck-am:
-installcheck: installcheck-am
-install-exec-am:
-install-exec: install-exec-am
-
-install-data-am:
-install-data: install-data-am
-
-install-am: all-am
-       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-install: install-am
-uninstall-am:
-uninstall: uninstall-am
-all-am: Makefile
-all-redirect: all-am
+info:
+dvi:
+check: all
+       $(MAKE)
+installcheck:
+install-exec: 
+       @$(NORMAL_INSTALL)
+
+install-data: 
+       @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+       @:
+
+uninstall: 
+
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+       $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
 installdirs:
 
 
 mostlyclean-generic:
+       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
 
 clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
-       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f Makefile $(DISTCLEANFILES)
        -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
 
 maintainer-clean-generic:
-mostlyclean-am:  mostlyclean-generic
-
-mostlyclean: mostlyclean-am
-
-clean-am:  clean-generic mostlyclean-am
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean:  mostlyclean-generic
 
-clean: clean-am
+clean:  clean-generic mostlyclean
 
-distclean-am:  distclean-generic clean-am
+distclean:  distclean-generic clean
+       -rm -f config.status
 
-distclean: distclean-am
-
-maintainer-clean-am:  maintainer-clean-generic distclean-am
+maintainer-clean:  maintainer-clean-generic distclean
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
-maintainer-clean: maintainer-clean-am
-
-.PHONY: tags distdir info-am info dvi-am dvi check check-am \
-installcheck-am installcheck install-exec-am install-exec \
-install-data-am install-data install-am install uninstall-am uninstall \
-all-redirect all-am all installdirs mostlyclean-generic \
-distclean-generic clean-generic maintainer-clean-generic clean \
-mostlyclean distclean maintainer-clean
+.PHONY: tags distdir info dvi installcheck install-exec install-data \
+install uninstall all installdirs mostlyclean-generic distclean-generic \
+clean-generic maintainer-clean-generic clean mostlyclean distclean \
+maintainer-clean
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
index 448cad78b077ec2efb1c036526a172d9ce61cda0..f7f22830488e2c883fc384a345bf9595b8fb6eb4 100644 (file)
 #undef EXTERNAL_OVERFLOW
 #undef DONT_FREE_FIRST
 
+/* Make automake happy */
+#undef PACKAGE
+#undef VERSION
+
 /* sysdep */
 #undef SYSDEP_DIR
 
 
 /* Define if you have the m library (-lm).  */
 #undef HAVE_LIBM
-
-/* Name of package */
-#undef PACKAGE
-
-/* Version number of package */
-#undef VERSION
-
index 582882b6d76e39fc6a3dc69f828af9753eabe6ce..5427420225ebb8abe98acc3bc1ef500731da8fdf 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,7 +1,7 @@
 #! /bin/sh
 
 # Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.13 
+# Generated automatically using autoconf version 2.12 
 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
 #
 # This configure script is free software; the Free Software Foundation
@@ -54,7 +54,6 @@ mandir='${prefix}/man'
 # Initialize some other variables.
 subdirs=
 MFLAGS= MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
 # Maximum number of lines to put in a shell here document.
 ac_max_here_lines=12
 
@@ -338,7 +337,7 @@ EOF
     verbose=yes ;;
 
   -version | --version | --versio | --versi | --vers)
-    echo "configure generated by autoconf version 2.13"
+    echo "configure generated by autoconf version 2.12"
     exit 0 ;;
 
   -with-* | --with-*)
@@ -508,11 +507,9 @@ ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
 cross_compiling=$ac_cv_prog_cc_cross
 
-ac_exeext=
-ac_objext=o
 if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
   # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
   if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
@@ -547,26 +544,26 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
 
 
 # Make sure we can run config.sub.
-if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+if $ac_config_sub sun4 >/dev/null 2>&1; then :
 else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
 fi
 
 echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:556: checking host system type" >&5
+echo "configure:553: checking host system type" >&5
 
 host_alias=$host
 case "$host_alias" in
 NONE)
   case $nonopt in
   NONE)
-    if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+    if host_alias=`$ac_config_guess`; then :
     else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
     fi ;;
   *) host_alias=$nonopt ;;
   esac ;;
 esac
 
-host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host=`$ac_config_sub $host_alias`
 host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
 host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
 host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
@@ -580,30 +577,28 @@ echo "$ac_t""$host" 1>&6
 # SunOS /usr/etc/install
 # IRIX /sbin/install
 # AIX /bin/install
-# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
 # AFS /usr/afsws/bin/install, which mishandles nonexistent args
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:589: checking for a BSD compatible install" >&5
+echo "configure:585: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-    IFS="${IFS=        }"; ac_save_IFS="$IFS"; IFS=":"
+    IFS="${IFS=        }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
   for ac_dir in $PATH; do
     # Account for people who put trailing slashes in PATH elements.
     case "$ac_dir/" in
     /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
     *)
       # OSF1 and SCO ODT 3.0 have their own names for install.
-      # Don't use installbsd from OSF since it installs stuff as root
-      # by default.
-      for ac_prog in ginstall scoinst install; do
+      for ac_prog in ginstall installbsd scoinst install; do
         if test -f $ac_dir/$ac_prog; then
          if test $ac_prog = install &&
             grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
            # AIX install.  It has an incompatible calling convention.
+           # OSF/1 installbsd also uses dspmsg, but is usable.
            :
          else
            ac_cv_path_install="$ac_dir/$ac_prog -c"
@@ -633,12 +628,13 @@ echo "$ac_t""$INSTALL" 1>&6
 # It thinks the first close brace ends the variable substitution.
 test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
 
-test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
-
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
 echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
-echo "configure:642: checking whether build environment is sane" >&5
+echo "configure:638: checking whether build environment is sane" >&5
 # Just in case
 sleep 1
 echo timestamp > conftestfile
@@ -695,7 +691,7 @@ test "$program_suffix" != NONE &&
 test "$program_transform_name" = "" && program_transform_name="s,x,x,"
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:699: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:695: checking whether ${MAKE-make} sets \${MAKE}" >&5
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -741,7 +737,7 @@ EOF
 
 missing_dir=`cd $ac_aux_dir && pwd`
 echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
-echo "configure:745: checking for working aclocal" >&5
+echo "configure:741: checking for working aclocal" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -754,7 +750,7 @@ else
 fi
 
 echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
-echo "configure:758: checking for working autoconf" >&5
+echo "configure:754: checking for working autoconf" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -767,7 +763,7 @@ else
 fi
 
 echo $ac_n "checking for working automake""... $ac_c" 1>&6
-echo "configure:771: checking for working automake" >&5
+echo "configure:767: checking for working automake" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -780,7 +776,7 @@ else
 fi
 
 echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
-echo "configure:784: checking for working autoheader" >&5
+echo "configure:780: checking for working autoheader" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -793,7 +789,7 @@ else
 fi
 
 echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
-echo "configure:797: checking for working makeinfo" >&5
+echo "configure:793: checking for working makeinfo" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -850,16 +846,15 @@ EOF
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:854: checking for $ac_word" >&5
+echo "configure:850: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
-  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
-  ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
     test -z "$ac_dir" && ac_dir=.
     if test -f $ac_dir/$ac_word; then
       ac_cv_prog_CC="gcc"
@@ -880,17 +875,16 @@ if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:884: checking for $ac_word" >&5
+echo "configure:879: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
-  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
   ac_prog_rejected=no
-  ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do
+  for ac_dir in $PATH; do
     test -z "$ac_dir" && ac_dir=.
     if test -f $ac_dir/$ac_word; then
       if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
@@ -925,61 +919,25 @@ else
   echo "$ac_t""no" 1>&6
 fi
 
-  if test -z "$CC"; then
-    case "`uname -s`" in
-    *win32* | *WIN32*)
-      # Extract the first word of "cl", so it can be a program name with args.
-set dummy cl; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:935: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
-  ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      ac_cv_prog_CC="cl"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
-  echo "$ac_t""$CC" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
- ;;
-    esac
-  fi
   test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:967: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:927: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
 cross_compiling=$ac_cv_prog_cc_cross
 
-cat > conftest.$ac_ext << EOF
-
-#line 978 "configure"
+cat > conftest.$ac_ext <<EOF
+#line 937 "configure"
 #include "confdefs.h"
-
 main(){return(0);}
 EOF
-if { (eval echo configure:983: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:941: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -993,24 +951,18 @@ else
   ac_cv_prog_cc_works=no
 fi
 rm -fr conftest*
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
 
 echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
 if test $ac_cv_prog_cc_works = no; then
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1009: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:961: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:1014: checking whether we are using GNU C" >&5
+echo "configure:966: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1019,7 +971,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1023: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:975: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -1030,15 +982,11 @@ echo "$ac_t""$ac_cv_prog_gcc" 1>&6
 
 if test $ac_cv_prog_gcc = yes; then
   GCC=yes
-else
-  GCC=
-fi
-
-ac_test_CFLAGS="${CFLAGS+set}"
-ac_save_CFLAGS="$CFLAGS"
-CFLAGS=
-echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:1042: checking whether ${CC-cc} accepts -g" >&5
+  ac_test_CFLAGS="${CFLAGS+set}"
+  ac_save_CFLAGS="$CFLAGS"
+  CFLAGS=
+  echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:990: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1053,35 +1001,30 @@ rm -f conftest*
 fi
 
 echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
-if test "$ac_test_CFLAGS" = set; then
-  CFLAGS="$ac_save_CFLAGS"
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
+  if test "$ac_test_CFLAGS" = set; then
+    CFLAGS="$ac_save_CFLAGS"
+  elif test $ac_cv_prog_cc_g = yes; then
     CFLAGS="-g -O2"
   else
-    CFLAGS="-g"
-  fi
-else
-  if test "$GCC" = yes; then
     CFLAGS="-O2"
-  else
-    CFLAGS=
   fi
+else
+  GCC=
+  test "${CFLAGS+set}" = set || CFLAGS="-g"
 fi
 
 # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1076: checking for $ac_word" >&5
+echo "configure:1020: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$RANLIB"; then
   ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
 else
-  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
-  ac_dummy="$PATH"
-  for ac_dir in $ac_dummy; do
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
     test -z "$ac_dir" && ac_dir=.
     if test -f $ac_dir/$ac_word; then
       ac_cv_prog_RANLIB="ranlib"
@@ -1101,7 +1044,7 @@ fi
 
 
 echo $ac_n "checking for sin in -lm""... $ac_c" 1>&6
-echo "configure:1105: checking for sin in -lm" >&5
+echo "configure:1048: checking for sin in -lm" >&5
 ac_lib_var=`echo m'_'sin | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1109,7 +1052,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lm  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1113 "configure"
+#line 1056 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1120,7 +1063,7 @@ int main() {
 sin()
 ; return 0; }
 EOF
-if { (eval echo configure:1124: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1067: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1153,12 +1096,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
-echo "configure:1157: checking for $ac_hdr that defines DIR" >&5
+echo "configure:1100: checking for $ac_hdr that defines DIR" >&5
 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1162 "configure"
+#line 1105 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <$ac_hdr>
@@ -1166,7 +1109,7 @@ int main() {
 DIR *dirp = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:1170: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1113: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_header_dirent_$ac_safe=yes"
 else
@@ -1191,7 +1134,7 @@ done
 # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
 if test $ac_header_dirent = dirent.h; then
 echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
-echo "configure:1195: checking for opendir in -ldir" >&5
+echo "configure:1138: checking for opendir in -ldir" >&5
 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1199,7 +1142,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldir  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1203 "configure"
+#line 1146 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1210,7 +1153,7 @@ int main() {
 opendir()
 ; return 0; }
 EOF
-if { (eval echo configure:1214: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1157: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1232,7 +1175,7 @@ fi
 
 else
 echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
-echo "configure:1236: checking for opendir in -lx" >&5
+echo "configure:1179: checking for opendir in -lx" >&5
 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1240,7 +1183,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lx  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1244 "configure"
+#line 1187 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1251,7 +1194,7 @@ int main() {
 opendir()
 ; return 0; }
 EOF
-if { (eval echo configure:1255: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1198: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1274,7 +1217,7 @@ fi
 fi
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1278: checking how to run the C preprocessor" >&5
+echo "configure:1221: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1289,14 +1232,14 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1293 "configure"
+#line 1236 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1299: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+{ (eval echo configure:1242: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
 else
@@ -1306,31 +1249,14 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1310 "configure"
+#line 1253 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1316: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
-  :
-else
-  echo "$ac_err" >&5
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  CPP="${CC-cc} -nologo -E"
-  cat > conftest.$ac_ext <<EOF
-#line 1327 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1333: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+{ (eval echo configure:1259: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
 else
@@ -1342,8 +1268,6 @@ else
 fi
 rm -f conftest*
 fi
-rm -f conftest*
-fi
 rm -f conftest*
   ac_cv_prog_CPP="$CPP"
 fi
@@ -1354,12 +1278,12 @@ fi
 echo "$ac_t""$CPP" 1>&6
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1358: checking for ANSI C header files" >&5
+echo "configure:1282: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1363 "configure"
+#line 1287 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -1367,8 +1291,8 @@ else
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1371: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+{ (eval echo configure:1295: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
   ac_cv_header_stdc=yes
@@ -1384,7 +1308,7 @@ rm -f conftest*
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1388 "configure"
+#line 1312 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -1402,7 +1326,7 @@ fi
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1406 "configure"
+#line 1330 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -1423,7 +1347,7 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 1427 "configure"
+#line 1351 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1434,7 +1358,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
 exit (0); }
 
 EOF
-if { (eval echo configure:1438: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1362: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -1461,18 +1385,18 @@ for ac_hdr in fcntl.h sys/time.h unistd.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1465: checking for $ac_hdr" >&5
+echo "configure:1389: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1470 "configure"
+#line 1394 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1475: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+{ (eval echo configure:1399: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
   eval "ac_cv_header_$ac_safe=yes"
@@ -1499,12 +1423,12 @@ done
 
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:1503: checking for working const" >&5
+echo "configure:1427: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1508 "configure"
+#line 1432 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -1553,7 +1477,7 @@ ccp = (char const *const *) p;
 
 ; return 0; }
 EOF
-if { (eval echo configure:1557: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1481: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -1574,21 +1498,21 @@ EOF
 fi
 
 echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:1578: checking for inline" >&5
+echo "configure:1502: checking for inline" >&5
 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_inline=no
 for ac_kw in inline __inline__ __inline; do
   cat > conftest.$ac_ext <<EOF
-#line 1585 "configure"
+#line 1509 "configure"
 #include "confdefs.h"
 
 int main() {
 } $ac_kw foo() {
 ; return 0; }
 EOF
-if { (eval echo configure:1592: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1516: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_inline=$ac_kw; break
 else
@@ -1614,12 +1538,12 @@ EOF
 esac
 
 echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:1618: checking for off_t" >&5
+echo "configure:1542: checking for off_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1623 "configure"
+#line 1547 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1628,7 +1552,7 @@ else
 #endif
 EOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  egrep "off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
   rm -rf conftest*
   ac_cv_type_off_t=yes
 else
@@ -1647,12 +1571,12 @@ EOF
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:1651: checking for size_t" >&5
+echo "configure:1575: checking for size_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1656 "configure"
+#line 1580 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1661,7 +1585,7 @@ else
 #endif
 EOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  egrep "size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
   rm -rf conftest*
   ac_cv_type_size_t=yes
 else
@@ -1680,12 +1604,12 @@ EOF
 fi
 
 echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:1684: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:1608: checking whether time.h and sys/time.h may both be included" >&5
 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1689 "configure"
+#line 1613 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/time.h>
@@ -1694,7 +1618,7 @@ int main() {
 struct tm *tp;
 ; return 0; }
 EOF
-if { (eval echo configure:1698: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1622: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_header_time=yes
 else
@@ -1715,12 +1639,12 @@ EOF
 fi
 
 echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
-echo "configure:1719: checking whether struct tm is in sys/time.h or time.h" >&5
+echo "configure:1643: checking whether struct tm is in sys/time.h or time.h" >&5
 if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1724 "configure"
+#line 1648 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <time.h>
@@ -1728,7 +1652,7 @@ int main() {
 struct tm *tp; tp->tm_sec;
 ; return 0; }
 EOF
-if { (eval echo configure:1732: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1656: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_tm=time.h
 else
@@ -1751,13 +1675,13 @@ fi
 
 if test $ac_cv_prog_gcc = yes; then
     echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
-echo "configure:1755: checking whether ${CC-cc} needs -traditional" >&5
+echo "configure:1679: checking whether ${CC-cc} needs -traditional" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     ac_pattern="Autoconf.*'x'"
   cat > conftest.$ac_ext <<EOF
-#line 1761 "configure"
+#line 1685 "configure"
 #include "confdefs.h"
 #include <sgtty.h>
 Autoconf TIOCGETP
@@ -1775,7 +1699,7 @@ rm -f conftest*
 
   if test $ac_cv_prog_gcc_traditional = no; then
     cat > conftest.$ac_ext <<EOF
-#line 1779 "configure"
+#line 1703 "configure"
 #include "confdefs.h"
 #include <termio.h>
 Autoconf TCGETA
@@ -1797,7 +1721,7 @@ echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
 fi
 
 echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6
-echo "configure:1801: checking for 8-bit clean memcmp" >&5
+echo "configure:1725: checking for 8-bit clean memcmp" >&5
 if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1805,7 +1729,7 @@ else
   ac_cv_func_memcmp_clean=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 1809 "configure"
+#line 1733 "configure"
 #include "confdefs.h"
 
 main()
@@ -1815,7 +1739,7 @@ main()
 }
 
 EOF
-if { (eval echo configure:1819: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1743: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_memcmp_clean=yes
 else
@@ -1830,24 +1754,24 @@ fi
 fi
 
 echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6
-test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}"
+test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.o"
 
 for ac_hdr in unistd.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1840: checking for $ac_hdr" >&5
+echo "configure:1764: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1845 "configure"
+#line 1769 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1850: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+{ (eval echo configure:1774: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
   eval "ac_cv_header_$ac_safe=yes"
@@ -1875,12 +1799,12 @@ done
 for ac_func in getpagesize
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1879: checking for $ac_func" >&5
+echo "configure:1803: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1884 "configure"
+#line 1808 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1903,7 +1827,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1907: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1831: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -1928,7 +1852,7 @@ fi
 done
 
 echo $ac_n "checking for working mmap""... $ac_c" 1>&6
-echo "configure:1932: checking for working mmap" >&5
+echo "configure:1856: checking for working mmap" >&5
 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1936,7 +1860,7 @@ else
   ac_cv_func_mmap_fixed_mapped=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 1940 "configure"
+#line 1864 "configure"
 #include "confdefs.h"
 
 /* Thanks to Mike Haertel and Jim Avera for this test.
@@ -2076,7 +2000,7 @@ main()
 }
 
 EOF
-if { (eval echo configure:2080: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2004: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_mmap_fixed_mapped=yes
 else
@@ -2099,12 +2023,12 @@ EOF
 fi
 
 echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:2103: checking return type of signal handlers" >&5
+echo "configure:2027: checking return type of signal handlers" >&5
 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2108 "configure"
+#line 2032 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <signal.h>
@@ -2121,7 +2045,7 @@ int main() {
 int i;
 ; return 0; }
 EOF
-if { (eval echo configure:2125: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2049: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_type_signal=void
 else
@@ -2142,12 +2066,12 @@ EOF
 for ac_func in getcwd gettimeofday mkdir mktime select socket
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2146: checking for $ac_func" >&5
+echo "configure:2070: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2151 "configure"
+#line 2075 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2170,7 +2094,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2174: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2098: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2197,12 +2121,12 @@ done
 
 if test $ac_cv_func_mmap_fixed_mapped = yes; then
        echo $ac_n "checking whether MAP_FAILED is defined""... $ac_c" 1>&6
-echo "configure:2201: checking whether MAP_FAILED is defined" >&5
+echo "configure:2125: checking whether MAP_FAILED is defined" >&5
 if eval "test \"`echo '$''{'ac_cv_map_failed'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2206 "configure"
+#line 2130 "configure"
 #include "confdefs.h"
 #include <sys/mman.h>
                                     #ifdef MAP_FAILED
@@ -2224,12 +2148,12 @@ fi
 echo "$ac_t""$ac_cv_map_failed" 1>&6
 
        echo $ac_n "checking whether MAP_ANONYMOUS is defined""... $ac_c" 1>&6
-echo "configure:2228: checking whether MAP_ANONYMOUS is defined" >&5
+echo "configure:2152: checking whether MAP_ANONYMOUS is defined" >&5
 if eval "test \"`echo '$''{'ac_cv_map_anonymous'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2233 "configure"
+#line 2157 "configure"
 #include "confdefs.h"
 #include <sys/mman.h>
                                     #ifdef MAP_ANONYMOUS
@@ -2281,7 +2205,7 @@ fi
 
 
 echo $ac_n "checking whether to include threads support""... $ac_c" 1>&6
-echo "configure:2285: checking whether to include threads support" >&5
+echo "configure:2209: checking whether to include threads support" >&5
 if test x"$enable_threads" = "xno"; then
        echo "$ac_t""no" 1>&6
 else
@@ -2307,7 +2231,7 @@ EOF
 fi
 
 echo $ac_n "checking which garbage collector to use""... $ac_c" 1>&6
-echo "configure:2311: checking which garbage collector to use" >&5
+echo "configure:2235: checking which garbage collector to use" >&5
 if test x"$enable_gc2" = "xno"; then
        echo "$ac_t""old garbage collector" 1>&6
        GC_OBJ="mm/libmm_old.a"
@@ -2341,7 +2265,7 @@ EOF
 # Ultrix sh set writes to stderr and can't be redirected directly,
 # and sets the high bit in the cache file unless we assign to the vars.
 (set) 2>&1 |
-  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  case `(ac_space=' '; set) 2>&1` in
   *ac_space=\ *)
     # `set' does not quote correctly, so add quotes (double-quote substitution
     # turns \\\\ into \\, and sed turns \\ into \).
@@ -2408,7 +2332,7 @@ do
     echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
     exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
   -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
-    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    echo "$CONFIG_STATUS generated by autoconf version 2.12"
     exit 0 ;;
   -help | --help | --hel | --he | --h)
     echo "\$ac_cs_usage"; exit 0 ;;
@@ -2427,8 +2351,9 @@ trap 'rm -fr `echo "Makefile \
           alpha/Makefile \
           mips/Makefile \
           nat/Makefile \
+          doc/Makefile \
           comp/Makefile \
-         doc/Makefile \
+         narray/Makefile \
          tst/Makefile  config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
 EOF
 cat >> $CONFIG_STATUS <<EOF
@@ -2438,11 +2363,9 @@ sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
  s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
 $ac_vpsub
 $extrasub
-s%@SHELL@%$SHELL%g
 s%@CFLAGS@%$CFLAGS%g
 s%@CPPFLAGS@%$CPPFLAGS%g
 s%@CXXFLAGS@%$CXXFLAGS%g
-s%@FFLAGS@%$FFLAGS%g
 s%@DEFS@%$DEFS%g
 s%@LDFLAGS@%$LDFLAGS%g
 s%@LIBS@%$LIBS%g
@@ -2467,8 +2390,8 @@ s%@host_cpu@%$host_cpu%g
 s%@host_vendor@%$host_vendor%g
 s%@host_os@%$host_os%g
 s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
-s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
 s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
 s%@PACKAGE@%$PACKAGE%g
 s%@VERSION@%$VERSION%g
 s%@ACLOCAL@%$ACLOCAL%g
@@ -2536,8 +2459,9 @@ CONFIG_FILES=\${CONFIG_FILES-"Makefile \
           alpha/Makefile \
           mips/Makefile \
           nat/Makefile \
+          doc/Makefile \
           comp/Makefile \
-         doc/Makefile \
+         narray/Makefile \
          tst/Makefile "}
 EOF
 cat >> $CONFIG_STATUS <<\EOF
diff --git a/doc/array.tex b/doc/array.tex
new file mode 100644 (file)
index 0000000..b64068d
--- /dev/null
@@ -0,0 +1,375 @@
+\documentclass[12pt]{article}
+
+\begin{document}
+
+\title{Array Bound-Check Removal}
+\author{Kruegel Christopher\\TU Vienna\\cacao@complang.tuwien.ac.at}
+\maketitle
+
+\section{Introduction}
+
+In safe programming languages like Java, all array accesses are 
+checked. It is assured that the used index is greater or equal to 
+zero and less than the array length, otherwise an 
+ArrayIndexOutOfBoundsException is thrown. It is obvious that this 
+gain in saftey causes a run-time overhead that is especially 
+unpleasant in loops where these checks have to be performed many 
+times. Often it is possible to remove these checks in loops by 
+inserting additional tests at the beginning of the loop and 
+examinig the code structure and loop condition thereby saving run-
+time speed at each loop execuion. The following algorithm performs 
+this task for a special set of array accesses in loops. It should 
+be obvious that it is not always possible to predict the value of 
+an array index by inserting tests at the beginning of the loop. An 
+example would be a global variable that is used as an array index. 
+This variable could be changed by a different thread virtually any 
+time, so removing a bound check for this array access is not a 
+good idea. The following algorithm only performs bound check 
+removal, when the induction variable (the variable used as array 
+index) is local and is only modified by adding/subtracting a 
+constant inside the loop body or remains unchanged (is constant). 
+If a constant is used as index, optimzation can take place as 
+well. When other variables are used to modify the induction 
+variable or when different arithmetic operations are used, no 
+optimization can take place. Nevertheless, the most common use for 
+index variables in loops is their increment or decrement by a 
+constant, so most of the array access should be considered for 
+optimization. 
+
+\section{Initialization}
+
+Before array bound checks in loops can be eliminated, the loops 
+have to be detected. The algorithm performs its analysis on 
+intermediate code level, so we cannot rely on just looking at 
+while/for statments. A basic block analysis has been completed, so 
+the algorithm can work on this data structure already. It uses the 
+Lengauer-Tarjan algorithm to find existing loops, which bases on 
+determining the dominator tree (a reference with extensive 
+documentation for this algorithm can be found in \cite{tig}). It uses a 
+depth first search on the control flow graph to build a spanning 
+tree. Then the semidominator and dominator theorem are utilized to 
+extract the dominator tree and by looking at back edges (a back 
+edge is an edge where the target node dominates the source node) 
+all loops can be detected. Before starting to look at each loop, 
+the case of different loops that share the same header node has to 
+be considered. The algorithm works on each loop not looking on any 
+other loop and performs its optimzation. The procedures that 
+analyze the control flow of the program, build a flow graph and 
+extract the loops can be found in the files graph.c (for control 
+flow graph) and loop.c (for the loop extractig algorithm). The 
+control flow graph is simple built by looking at the last 
+instruction of each basic block and then deciding, which other 
+blocks can be reached by that instruction. One problem can occur, 
+when lookup/table-switch instructions cause multiple jumps to the 
+same node. It must be prevented that the target node´s predecessor 
+list contains that node more than once. So an additionally array 
+is needed to prevent double entries in the predecessor array. When 
+the necessary flow data structure and the list of all loops has 
+been built, the main algorithm can start.
+
+
+\section{Algorithm}
+
+The procedures for the main algorithm can be found in analyze.c. 
+Before each loops is processed on its own, two global 
+preprocessing steps are necessary.
+
+The first step deals with loops, that share the same header node. 
+This special case can happen when a loop body ends with an if-
+then/else statment. The loop finding algorithm then reports two 
+different loops, which share the same header node. When additional 
+tests are inserted at the header node and another loop sharing the 
+same header is later evaluated, inserting different tests, 
+problems could arise. To prevent this from happening, loops 
+sharing the same header node are simply merged into a bigger one 
+by unioning their nodes. Because the nodes of the loop are already 
+sorted by increasing basic block numbers, a simple merge of the 
+nodes can be done (analyze\_double\_headers).
+
+The second step before the loop by loop analysis commences is the 
+building of a loop hierarchie. Nested loops cause problems when 
+variables that are used as array indexes elsewhere get modified. 
+Because these modifications (eg. an increment by a constant) can 
+happen an unknown number of times, their results are 
+unpredictable. These modifications in nested loops have to be 
+recognized and reacted upon accordingly. The algorithm builds a 
+tree where each node represents a loop with its parent being the 
+directly surrounding loop. A dummy root node, representing the 
+whole function has to be inserted as well. When loops have to be 
+duplicated because of optimzed array accesses, it is important to 
+extend or duplicate exception entries as well. Because of that, 
+exceptions are inserted into the tree as follows. Every exception 
+is inserted at the node in the hierarchie that represents the 
+loop, that directly contains this exception. When an exception is 
+part of a nested loop, it is inserted only at the node, 
+representing this nested loop, because by following this nodes 
+parent pointers, we find all other loops, that contain the 
+exception (analyze\_nested). Finally, the sequentiel order of the 
+loops is determined by a topological sort of the loops, satisfying 
+the condition, that all nested loops have to be optimzed before 
+their parent loop is processed. This can be archieved by a post-
+order traversal of the hierarchie tree with skipping the root 
+node.  
+
+After these global steps have been completed, each loop is 
+processed. Then the loops are checked for array accesses 
+(analyze\_for\_array\_access) and the process exits if none 
+are found. Finally, two special cases must be considered.
+
+\begin{enumerate}
+
+\item The algorithm uses the loop condition to guarantee certain 
+bounds for variables. If the loop condition consists of an or-
+statement, these guarantees can not be held up. If the loop 
+statement reads 
+
+\begin{verbatim}
+while ((var > 0) or true) 
+\end{verbatim}
+
+vars value is not  bound to be greater than zero. When an or-statement
+is found, loop optimization is stopped.
+
+\item Variables that are used as indexes in array accesses might be 
+modified in exception handling code of try-catch statements inside 
+the loop. Because code in catch blocks is not considered in the 
+control flow graph and because these modifications happen 
+unpredictable (and should occur rarely) loops containing these 
+catch blocks with index variable modifications are not optimized.
+During the scan for array accesses within the loop, all 
+interesting variables are recorded. A variable is considered 
+interesting, when it is used as index in an array access or when 
+its value is changes (due to a store instruction) 
+(analyze\_or\_exceptions and scan\_global\_list).
+
+\end{enumerate}
+
+The next step is responsible for the analyzation of the loop 
+condition itself. The loop condition can create a so called 
+dynamic constraint on a variable. If one side of the loop 
+condition is constant during the execution of the loop the other 
+side can be safely assumed to be less than, greater or equal 
+than or equal to this side (depending on the operator) at the 
+start of each loop pass. It is important to notice the difference 
+to so called static constraints on variables. That means that 
+these variables can be safely assumed to stay below or above a 
+certain constant during the loop execution by simple testing them 
+prior to loop entry. This is obviously true for constants but does 
+also hold for variables that are only decremented or incremented. 
+For these, a static lower or upper bound can be guaranteed for the 
+whole loop execution by simply inserting a single test prior to 
+loop entry. Dynamic constraints, on the contrary, can vary in 
+different parts of the loop. After the variable is tested in the 
+loop condition, it might be changed to different values in 
+different paths of execution. All variables, that are never 
+changed or that get only decremented/incremented have static and 
+dynamic constraints, all others can only have dynamic ones 
+(init\_constraint). 
+
+Now the core bound check removal procedure is started. Beginning 
+directly after the loop condition all changes of variables that 
+are used as index variables somewhere in the loop are recorded. 
+This is an iterative process since different paths of execution 
+may yield different changes to these variables. Especially changes 
+in nested loops cause these changes to become unpredictable and 
+therefore no upper/lower bound can be held up any further. After 
+this iterative process caused all changes to become stable, each 
+array access is examined (e.g. a statement like
+\newpage
+\begin{verbatim}
+if (x == true) 
+    i++; 
+else 
+    i+=2; 
+\end{verbatim}
+must result in an increase of 2 for i when control 
+flow joins after the if-statement). If it is possible, by 
+inserting additional static/dynamic tests as needed, to assure 
+that the index variable is greater or equal to zero and less than 
+the array length, the bound checks are removed 
+(remove\_bound\_checks). It is possible that more than one static 
+tests gets inserted for a single variable, when it is used in 
+different array access (possibly with different constants added or 
+subtracted). Because all tests have to hold for this variable to 
+allow optimzed code to be executed, only the strictest tests have 
+to be done (e.g. if an integer array x[] is accessed by i in the 
+statements x[i+1] and x[i-1], it has to be guaranteed that i $>$ 1 
+(for second statement) and that i $<$ arraylength-1 (for the first 
+statement)). Parallel to the insertion of new tests, the number of 
+needed instructions for the new loop header node is accordingly 
+increased. When optimzing the loop, it is important to 
+differentiate between the loop head and the rest of the basic 
+blocks, forming the body. The dynamic constraints can only be used 
+for array accesses in the loop body, as the loop comparison is 
+done at the end of the header node. Nevertheless, all static 
+constraints can still be used to optimze array access in the 
+header block. Because it is possible that an array reference is 
+null prior to entering the loop, all array references that are 
+loaded to compute an arraylength have to be checked against null.
+
+After all new tests have been determined, it is necessary to 
+reorder the code and insert the new tests (insert\_static\_checks). 
+The first step is the creation of a new header node. Because all 
+jumps to the beginning of the old loop now have to get to the new 
+header first, it is more efficient to just replace the code in the 
+old header block by the new tests. So only jumps within the loops 
+need to be patched and the rest of the code can remain untouched. 
+For each constraint that has been found in the previous step of 
+the algorithm, two values have to be loaded and are then compared. 
+Because it is possible during runtime that these tests fail (and 
+no guarantee can be made) a copy of the loop with the original, 
+checked array accesses must exist. Depending on the outcome of the 
+test cascade, a jump to the optimized or original loop is made. To 
+copy the loop, all basic blocks that are part of the loop are 
+copied and appended to the end of the global basic block list. 
+After that, both the original and the copy of the loop need post- 
+processing to redirect certain jump targets. All jumps to the old 
+loop head (which now contains the static checks) in the original 
+loop have to be redirected to the newly inserted block, that holds 
+the code for the original loop head. In the copied loop, all jumps 
+inside the loop have to be redirected to jumps to the copied 
+blocks. When loops are duplicated, these changes must be reflected 
+in the node list of all parent loops as well. So the hierarchie 
+tree is climbed and the new nodes are added to all enclosing 
+loops. Because these node lists are sorted, it is necessary to 
+deal with the new loop head in a different way. The loop head has 
+to be inserted into the correct place of the parent loops while 
+all other copied nodes can simply be appended to the basic block 
+list. 
+
+Now all exceptions have to be examined. There are three different 
+cases, that must be considered. An exception can be part of the 
+loop body (ie. is inside the loop), an exception can contain the 
+loop or an exception is in a different part of the code (and does 
+not have to be further considered). To be able to find all 
+exceptions that are part of the loop, the algorithm uses the 
+hierarchie tree and gets all exceptions of all children nodes. The 
+exception handlers of these loops have to be copied and jumps to 
+the original loop have to be redirected to the copied loop. The 
+start and end code pointers of the protected area have to be moved 
+to the copied blocks. The exception handler code is identified by 
+looking at the successor nodes starting from the handler block. As 
+long as control flow does not reach a loop node again, all blocks 
+are considered as part of the handler code. Exceptions that 
+surround the loop have to be handled different. It is not 
+necessary to copy the exception handler, as it is not part of the 
+loop. Nevertheless it is important to extend the protected area to 
+the copied blocks. So the first and last block (including copied 
+exception handler blocks of nested loops) that got copied are 
+stored. The exceptions are then extended to contain all these new 
+blocks and jump to the original handler. As no code is duplicated, 
+nothing needs to be patched. When climbing up the hierarchie tree 
+by following the parent pointer, not all exceptions of parent 
+nodes really enclose the loop. It is possible that a parent loop 
+contains an exception and the loop, that is optimized, right after 
+each other. Those exceptions must not be handled and are ignored. 
+Because of the layout of the exception table, where appropriate 
+exceptions (that could be nested) are found by a linear search 
+from the start, it is necessary to insert newly created exceptions 
+right after their original ones. 
+
+One performance problem still remains after these modifications. 
+The new loop header that replaces the original one is located 
+exactly where the old one was. A fall through from the previous 
+block (that could be part of the loop) to the loop header must be 
+patched by inserting an additional goto-instruction to the 
+original head of the loop. Because this would insert an additional 
+jump into the loop body, performance may deteriorate. To solve 
+this shortcoming, the new loop head has to be moved before the 
+first node of the loop. This might cause the problem of moving the 
+loop head to the beginning of the global basic block list. This 
+pointer points to the initial basic block array and can not be 
+easily reassigned. A new pointer is needed that temporary holds 
+the begin of the basic block list and is assigned to the original 
+pointer after all optimization step have been finished. Any fall 
+through from the predecessor of the loop head now reaches the old 
+loop head, that has been inserted right after the new loop head. 
+After all loops have been processed, register allocation and code 
+genration proceed as usual and optimized code is generated.
+
+\section{Helper functions}
+
+An important helper function is stored in tracing.c. This 
+functions is needed to determine the variables/constants that 
+participate in array accesses or comparisons. As all work is done 
+on java bytecode, it is necessary to find the arguments of an 
+interesting operation by examining the stack. Unfortunately these 
+values can just be temporary and origin in variables loaded 
+earlier and getting modified by arithmetic operations. To find the 
+variables that participate in an array access, one has to walk 
+back instructions and looking at the stack, until an appropriate 
+load is found. The function tracing preforms this task by steping 
+back instruction for instruction and record the stack changes 
+these instructions cause until the correct load or push constant 
+operating has been found or until it becomes clear, that it is 
+impossible to determine the origin (e.g. when a function return 
+value is used). The value is then delivered in a special structure 
+and used by the main algorithm. 
+
+\section{Performance - impact and gain}
+
+It is obvious that the optimization process causes additionally 
+compile time overhead but can give performance gains during 
+runtime, when 3 less instructions are executed per array access 
+many times in a loop. The additional overhaed is mainly caused by 
+the needed control flow analysis, which has to be done for every 
+method and is linear to the number of basic blocks. Then the loop 
+scaning algorithm trys to find loops in the control flow graph. 
+This algorithm has to be started every time a method is compiled 
+and runs in O(n*ld(n)) where n is the number of basic blocks. 
+After the loops have been scanned for array access, the runtime of 
+the final bound check removal and loop copying process mainly 
+depends on the nesting depth of the hierarchie tree. For every 
+additional nesting depth, the number of basic blocks, that must be 
+copied and patch is doubled, resulting in exponential overhead 
+according to the nesting depth. Additionally, the search for 
+modifications of index variables, which is an iterative process, 
+becomes slowed down by deeply nested loops. Things get worse when 
+many exceptions are involved, because not only exceptions in 
+children nodes have to be considered, but all enclosing exceptions 
+as well. Nevertheless those cases should rarely occur and in real 
+environments, the net gain can be significant. Especially in tight 
+loops, when arrays are initialized or their elements summed up, 
+three less instructions can gain up to 30 percent speedup, when loops run 
+many times.
+
+
+\subsection{Tables} 
+
+\vspace{4mm}
+
+\begin{tabular}{|l|c|c|c|}
+
+\hline
+
+& Compile time (in ms) & \multicolumn{2}{c|}{Run time (in ms) } \\
+
+\multicolumn{1}{|c|}{\raisebox{1ex}{Cacao Options}} & javac & perf & sieve 1000 1000\\ \hline 
+
+\rule{0mm}{5mm}with optimization (-oloop) & 176 & 1510 & 98 \\
+
+without optimization & 118 & 1720 & 131 \\ 
+
+\hline
+
+\end{tabular}
+
+\begin{thebibliography}{9}
+
+\bibitem{tig} A. Appel; modern compiler implementation in C; Cambridge University Press; 1998
+
+\bibitem{aho} A. Aho, R.Sethi, J. Ullman; Compilers - Principles, 
+Techniques, and Tools; Addison-Wesly; 1986
+
+\end{thebibliography}
+
+\end{document}
+
+
+
+
+
+
+
+
index 0cdf4817bab7c8233145b09cfb2c0586cc07bf62..a5e7c0db879d7fcae87584ac23648ccb3b2a7956 100644 (file)
--- a/global.h
+++ b/global.h
@@ -12,7 +12,7 @@
        Changes: Mark     Probst  (schani)   EMAIL: cacao@complang.tuwien.ac.at
                         Philipp  Tomsich (phil)     EMAIL: cacao@complang.tuwien.ac.at
 
-       Last Change: $Id: global.h 118 1999-01-20 14:58:16Z andi $
+       Last Change: $Id: global.h 132 1999-09-27 15:54:42Z chris $
 
 *******************************************************************************/
 
@@ -336,9 +336,27 @@ typedef struct fieldinfo {/* field of a class                                 */
 
 } fieldinfo;
 
+struct basicblock;
 
 /* exceptiontable *************************************************************/
 
+typedef struct xtable { /* exceptiontable entry in a method           */ 
+       s4         startpc;         /* start pc of guarded area (inclusive)       */
+       struct basicblock *start;
+
+       s4         endpc;           /* end pc of guarded area (exklusive)         */
+       struct basicblock *end;
+
+       s4         handlerpc;       /* pc of exception handler                    */
+       struct basicblock *handler;
+
+       classinfo *catchtype;       /* catchtype of exception (NULL == catchall)  */
+       struct xtable *next;        /* used to build a list of exception when     */
+                                   /* loops are copied */
+       struct xtable *down;        /* instead of the old array, a list is used   */
+} xtable;
+
+
 typedef struct exceptiontable { /* exceptiontable entry in a method           */ 
        s4         startpc;         /* start pc of guarded area (inclusive)       */
        s4         endpc;           /* end pc of guarded area (exklusive)         */
@@ -365,7 +383,8 @@ typedef struct methodinfo {         /* method structure                       */
        u1        *jcode;               /* pointer to JavaVM code                 */
 
        s4         exceptiontablelength;/* exceptiontable length                  */
-       exceptiontable *exceptiontable; /* the exceptiontable                     */
+       exceptiontable *exceptiontable; 
+                                    /* the exceptiontable                     */
 
        u1        *stubroutine;         /* stub for compiling or calling natives  */    
        s4         mcodelength;         /* legth of generated machine code        */
diff --git a/jit.c b/jit.c
index 989f4b741589a5d795ab6998eb42b9487f0794e8..7a69432a214c45a4b7699f93a1945d1913859714 100644 (file)
--- a/jit.c
+++ b/jit.c
 
 #include "threads/thread.h"
 
+/* include compiler data types ************************************************/ 
+
+#include "jit/jitdef.h"
+#include "narray/loop.h"
+
 
 /* global switches ************************************************************/
+int num_compiled_m = 0;
+int myCount;
 
 bool compileverbose = false;
 bool showstack = false;
@@ -41,6 +48,7 @@ bool checkbounds = true;
 bool checknull = true;
 bool checkfloats = true;
 bool checksync = true;
+bool opt_loops = false;
 
 bool getcompilingtime = false;
 long compilingtime = 0;
@@ -103,10 +111,6 @@ static int count_store_depth_init[11] = {0, 0, 0, 0, 0,  0, 0, 0, 0, 0,   0};
 int *count_store_depth = count_store_depth_init;
 
 
-/* include compiler data types ************************************************/ 
-
-#include "jit/jitdef.h"
-
 
 /* global compiler variables **************************************************/
 
@@ -124,7 +128,8 @@ static int maxlocals;           /* maximal number of local JavaVM variables   */
 static int jcodelength;         /* length of JavaVM-codes                     */
 static u1 *jcode;               /* pointer to start of JavaVM-code            */
 static int exceptiontablelength;/* length of exception table                  */
-static exceptiontable *extable; /* pointer to start of exception table        */
+static xtable *extable;         /* pointer to start of exception table        */
+static exceptiontable *raw_extable;
 
 static int block_count;         /* number of basic blocks                     */
 static basicblock *block;       /* points to basic block array                */
@@ -140,6 +145,8 @@ static stackelement *stack;     /* points to intermediate code instructions   */
 
 static bool isleafmethod;       /* true if a method doesn't call subroutines  */
 
+static basicblock *last_block;  /* points to the end of the BB list           */
+
 /* list of all classes used by the compiled method which have to be           */
 /* initialised (if not already done) before execution of this method          */
 
@@ -154,9 +161,11 @@ static chain *uninitializedclasses;
 #include "jit/parse.c"          /* parsing of JavaVM code                     */ 
 #include "jit/reg.c"            /* register allocation and support routines   */ 
 #include "jit/stack.c"          /* analysing the stack operations             */ 
-#include "ngen.c"        /* code generator                             */ 
-
-
+#include "sysdep/ngen.c"        /* code generator                             */ 
+#include "narray/graph.c"      /* array bound removal                        */
+#include "narray/loop.c"       /* array bound removal                        */
+#include "narray/tracing.c"    /* array bound removal                        */
+#include "narray/analyze.c"    /* array bound removal                        */
 
 
 /* dummy function, used when there is no JavaVM code available                */
@@ -181,9 +190,18 @@ methodptr compiler_compile (methodinfo *m); /* compile method with old compiler*
 
 methodptr jit_compile(methodinfo *m)
 {
-       int  dumpsize;
+       int  dumpsize, i, j, k;
        long starttime = 0;
        long stoptime  = 0;
+       basicblock *b;
+       instruction *ip;
+       stackptr sp;
+
+       basicblock *bptr;
+       stackptr sptr;
+       int cnt;
+
+
 
 #ifdef OLD_COMPILER
        if (!newcompiler) {
@@ -249,7 +267,7 @@ methodptr jit_compile(methodinfo *m)
        jcodelength = m->jcodelength;
        jcode = m->jcode;
        exceptiontablelength = m->exceptiontablelength;
-       extable = m->exceptiontable;
+       raw_extable = m->exceptiontable;
 
 #ifdef STATISTICS
        count_tryblocks += exceptiontablelength;
@@ -273,22 +291,60 @@ methodptr jit_compile(methodinfo *m)
        /* call the compiler passes ***********************************************/
        
        reg_init();
+
        local_init();
+
        mcode_init();
 
        parse();
 
        analyse_stack();
+   
+       if (opt_loops) {
+               depthFirst();                   
+#ifdef LOOP_DEBUG
+               resultPass1();                  
+               fflush(stdout);
+#endif 
+               analyseGraph();         
+#ifdef LOOP_DEBUG
+               resultPass2(); 
+               fflush(stdout);
+#endif 
+               optimize_loops();
+#ifdef LOOP_DEBUG
+               /* resultPass3(); */
+#endif 
+       }
+   
 
+#ifdef LOOP_DEBUG
+       printf("Allocating registers  ");
+       fflush(stdout);
+#endif 
        interface_regalloc();
-
+#ifdef LOOP_DEBUG
+       printf(".");
+       fflush(stdout);
+#endif 
        allocate_scratch_registers();
-       
+#ifdef LOOP_DEBUG
+       printf(".");
+       fflush(stdout); 
+#endif 
        local_regalloc();
-       
+#ifdef LOOP_DEBUG
+       printf(". done\n");
+
+       printf("Generating MCode ... ");
+       fflush(stdout);
+#endif 
        gen_mcode();
+#ifdef LOOP_DEBUG
+       printf("done\n");
+       fflush(stdout);
+#endif 
 
-       
        /* intermediate and assembly code listings ********************************/
                
        if (showintermediate)
@@ -299,8 +355,6 @@ methodptr jit_compile(methodinfo *m)
        if (showddatasegment)
                dseg_display((void*) (m->mcode));
 
-
-
        /* release dump area */
 
        dump_release (dumpsize);
@@ -331,8 +385,7 @@ methodptr jit_compile(methodinfo *m)
        /* return pointer to the methods entry point */
        
        return m -> entrypoint;
-}
-
+} 
 
 /* functions for compiler initialisation and finalisation *********************/
 
diff --git a/jit.h b/jit.h
index aa52b03c7ca696f7e342d7263c52ec53ae12afbb..3a34d92b7ea33c14669cf1ee0f98370cfccc0101 100644 (file)
--- a/jit.h
+++ b/jit.h
@@ -26,6 +26,7 @@ extern bool showintermediate;   /* generate intermediate code listing         */
 extern int  optimizelevel;      /* optimzation level  (0 = no optimization)   */
 
 extern bool checkbounds;        /* check array bounds                         */
+extern bool opt_loops;          /* optimize array accesses in loops           */
 extern bool checknull;          /* check null pointers                        */
 extern bool checkfloats;        /* implement ieee compliant floats            */
 extern bool checksync;          /* do synchronization                         */
index ab4de16fd919632193e85f727b965391cdbbf6af..72b1e79485fab0afe47ba7fc72a2ecb2f05add20 100644 (file)
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4 from Makefile.am
+# Makefile.in generated automatically by automake 1.3 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -11,7 +11,7 @@
 # PARTICULAR PURPOSE.
 
 
-SHELL = @SHELL@
+SHELL = /bin/sh
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -32,7 +32,7 @@ mandir = @mandir@
 includedir = @includedir@
 oldincludedir = /usr/include
 
-DESTDIR =
+DISTDIR =
 
 pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -46,7 +46,7 @@ AUTOMAKE = @AUTOMAKE@
 AUTOHEADER = @AUTOHEADER@
 
 INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 transform = @program_transform_name@
@@ -81,13 +81,14 @@ DIST_COMMON =  Makefile.am Makefile.in
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = tar
-GZIP_ENV = --best
-all: all-redirect
+GZIP = --best
+all: Makefile
+
 .SUFFIXES:
-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-       cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps jit/Makefile
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu jit/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -100,75 +101,67 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = jit
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu jit/Makefile
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
-         if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
-         else \
-           test -f $(distdir)/$$file \
-           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
-           || cp -p $$d/$$file $(distdir)/$$file || :; \
-         fi; \
+         test -f $(distdir)/$$file \
+         || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+         || cp -p $$d/$$file $(distdir)/$$file; \
        done
-info-am:
-info: info-am
-dvi-am:
-dvi: dvi-am
-check-am: all-am
-check: check-am
-installcheck-am:
-installcheck: installcheck-am
-install-exec-am:
-install-exec: install-exec-am
-
-install-data-am:
-install-data: install-data-am
-
-install-am: all-am
-       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-install: install-am
-uninstall-am:
-uninstall: uninstall-am
-all-am: Makefile
-all-redirect: all-am
+info:
+dvi:
+check: all
+       $(MAKE)
+installcheck:
+install-exec: 
+       @$(NORMAL_INSTALL)
+
+install-data: 
+       @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+       @:
+
+uninstall: 
+
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+       $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
 installdirs:
 
 
 mostlyclean-generic:
+       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
 
 clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
-       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f Makefile $(DISTCLEANFILES)
        -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
 
 maintainer-clean-generic:
-mostlyclean-am:  mostlyclean-generic
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean:  mostlyclean-generic
 
-mostlyclean: mostlyclean-am
+clean:  clean-generic mostlyclean
 
-clean-am:  clean-generic mostlyclean-am
+distclean:  distclean-generic clean
+       -rm -f config.status
 
-clean: clean-am
-
-distclean-am:  distclean-generic clean-am
-
-distclean: distclean-am
-
-maintainer-clean-am:  maintainer-clean-generic distclean-am
+maintainer-clean:  maintainer-clean-generic distclean
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
-maintainer-clean: maintainer-clean-am
-
-.PHONY: tags distdir info-am info dvi-am dvi check check-am \
-installcheck-am installcheck install-exec-am install-exec \
-install-data-am install-data install-am install uninstall-am uninstall \
-all-redirect all-am all installdirs mostlyclean-generic \
-distclean-generic clean-generic maintainer-clean-generic clean \
-mostlyclean distclean maintainer-clean
+.PHONY: tags distdir info dvi installcheck install-exec install-data \
+install uninstall all installdirs mostlyclean-generic distclean-generic \
+clean-generic maintainer-clean-generic clean mostlyclean distclean \
+maintainer-clean
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
index c55fc994fd0bfa7fc87a898cbbb5b52dbee32d35..5691143c611c7c3a3f56b1991ca7e1ec867c9da8 100644 (file)
@@ -80,6 +80,10 @@ struct instruction {
                double d;               /* double operand     */
                void *a;                /* address operand    */
                } val;                  /* immediate constant */
+
+       void *target;                           /* used for targets of branches and jumps         */
+                                                               /* and as address for list of targets for         */
+                                                               /* statements                                                             */
        };
 
 
@@ -108,6 +112,14 @@ struct basicblock {
        int          outdepth;      /* stack depth end of basic block             */
        int          pre_count;     /* count of predecessor basic blocks          */
        branchref   *branchrefs;    /* list of branches to be patched             */
+
+       basicblock      *next;                  /* used to build a BB list (instead of array) */
+       int                      lflags;                /* used during loop copying, init with 0          */
+       basicblock      *copied_to;             /* points to the copy of this basic block         */
+                                                               /* when loop nodes are copied                             */
+
+  int debug_nr;
+
        };
 
 
index 19d43519c20014c09142608657f26800215d7e8c..638101d4450ba2e54b4e06817101485aa92c2eaa 100644 (file)
@@ -323,9 +323,9 @@ static void mcode_finish(int mcodelen)
 
        jr = jumpreferences;
        while (jr != NULL) {
-               *((void**) (epoint + jr->tablepos)) = epoint + jr->target->mpc;
-               jr = jr->next;
-               }
+           *((void**) (epoint + jr->tablepos)) = epoint + jr->target->mpc;
+           jr = jr->next;
+           }
 }
 
 
index f9860e08c02f9c737d343207e8016537f0dd14c6..958068eb3b8b424da749681b4ce8741b08fec16a 100644 (file)
@@ -8,7 +8,7 @@
        
        Author: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
 
-       Last Change: $Id: parse.c 115 1999-01-20 01:52:45Z phil $
+       Last Change: $Id: parse.c 132 1999-09-27 15:54:42Z chris $
 
 *******************************************************************************/
 
@@ -288,7 +288,7 @@ static void parse()
        /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
        /* additional MONITOREXITS are reached by branches which are 3 bytes */
        
-       iptr = instr = DMNEW(instruction, jcodelength + 5);
+       iptr = instr = DMNEW(instruction, jcodelength + 5); 
        
        /* initialize block_index table (unrolled four times) */
 
@@ -305,19 +305,34 @@ static void parse()
 
        /* compute branch targets of exception table */
 
+       extable = DMNEW(xtable, exceptiontablelength + 1);
+
        for (i = 0; i < exceptiontablelength; i++) {
-               p = extable[i].startpc;
+
+               p = extable[i].startpc = raw_extable[i].startpc;
                bound_check(p);
                block_insert(p);
-               p = extable[i].endpc;
+
+               p = extable[i].endpc = raw_extable[i].endpc;
                bound_check1(p);
                if (p < jcodelength)
                        block_insert(p);
-               p = extable[i].handlerpc;
+
+               p = extable[i].handlerpc = raw_extable[i].handlerpc;
                bound_check(p);
                block_insert(p);
+
+               extable[i].catchtype  = raw_extable[i].catchtype;
+
+               extable[i].next = NULL;
+               extable[i].down = &extable[i+1];
                }
 
+       if (exceptiontablelength > 0)
+               extable[exceptiontablelength-1].down = NULL;
+       else
+               extable = NULL;
+
        s_count = 1 + exceptiontablelength; /* initialize stack element counter   */
 
 #ifdef USE_THREADS
@@ -1066,6 +1081,7 @@ static void parse()
        bptr = block = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
 
        b_count = 0;
+       c_debug_nr = 0;
        
        /* additional block if target 0 is not first intermediate instruction     */
 
@@ -1076,37 +1092,69 @@ static void parse()
                bptr->type = BBTYPE_STD;
                bptr->branchrefs = NULL;
                bptr->pre_count = 0;
+               bptr->debug_nr = c_debug_nr++;
                bptr++;
                b_count++;
+               (bptr - 1)->next = bptr;
+       
                }
 
        /* allocate blocks */
 
+
        for (p = 0; p < jcodelength; p++)
+               
                if (block_index[p] & 1) {
                        bptr->iinstr = instr + (block_index[p] >> 1);
+                       bptr->debug_nr = c_debug_nr++;
                        if (b_count != 0)
                                (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
                        bptr->mpc = -1;
                        bptr->flags = -1;
+                       bptr->lflags = 0;
                        bptr->type = BBTYPE_STD;
                        bptr->branchrefs = NULL;
                        block_index[p] = b_count;
                        bptr->pre_count = 0;
                        bptr++;
                        b_count++;
+
+                       (bptr - 1)->next = bptr;
                        }
 
        /* allocate additional block at end */
 
+       
+       bptr->instack = bptr->outstack = NULL;
+       bptr->indepth = bptr->outdepth = 0;
        bptr->iinstr = NULL;
        (bptr - 1)->icount = (instr + instr_count) - (bptr - 1)->iinstr;
        bptr->icount = 0;
        bptr->mpc = -1;
        bptr->flags = -1;
+       bptr->lflags = 0;
        bptr->type = BBTYPE_STD;
        bptr->branchrefs = NULL;
        bptr->pre_count = 0;
+       bptr->debug_nr = c_debug_nr++;
+                       
+       (bptr - 1)->next = bptr;
+       bptr->next = NULL;
+
+       last_block = bptr;
+
+
+
+       for (i = 0; i < exceptiontablelength; ++i) {
+               p = extable[i].startpc;
+               extable[i].start = block + block_index[p];
+
+               p = extable[i].endpc;
+               extable[i].end = block + block_index[p]; 
+
+               p = extable[i].handlerpc;
+               extable[i].handler = block + block_index[p];
+           }
        }
 }
 
index 1f9445b2d0c61b870251a3a49f8fa62f73a4233a..09bd3ad8ac06e7a59ac6baaf23d2ebb3b2d338cf 100644 (file)
--- a/jit/reg.c
+++ b/jit/reg.c
@@ -257,6 +257,7 @@ static void interface_regalloc ()
                saved = (interfaces[s][TYPE_INT].flags | interfaces[s][TYPE_LNG].flags |
                         interfaces[s][TYPE_FLT].flags | interfaces[s][TYPE_DBL].flags |
                         interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
                for (t = TYPE_INT; t <= TYPE_ADR; t++) {
                        v = &interfaces[s][t];
                        if (v->type >= 0) {
@@ -335,11 +336,13 @@ static void interface_regalloc ()
                                } /* if (type >= 0) */
                        }     /* for t */
                }         /* for s */
+
        maxmemuse = ifmemuse;
        maxtmpintreguse = iftmpintregcnt;
        maxsavintreguse = ifsavintregcnt;
        maxtmpfltreguse = iftmpfltregcnt;
        maxsavfltreguse = ifsavfltregcnt;
+
 }
 
 
@@ -595,18 +598,22 @@ static void allocate_scratch_registers()
        instruction *iptr = instr;
        basicblock  *bptr;
        
-       b_count = block_count;
+       /* b_count = block_count; */
+
        bptr = block;
-       while (--b_count >= 0) {
+       while (bptr != NULL) {
+
                if (bptr->flags >= BBREACHED) {
                        dst = bptr->instack;
                        reg_init_temp();
                        iptr = bptr->iinstr;
                        len = bptr->icount;
+  
                        while (--len >= 0)  {
                                src = dst;
                                dst = iptr->dst;
                                opcode = iptr->opc;
+
                                switch (opcode) {
 
                                        /* pop 0 push 0 */
@@ -1000,7 +1007,7 @@ static void allocate_scratch_registers()
                                iptr++;
                                } /* while instructions */
                        } /* if */
-               bptr++;
+               bptr = bptr->next;
        } /* while blocks */
 }
 
index 17ee4ed81750147f6fd2cbdc3b3ce47846e4e9d8..dd9fc35dd1a73d2ffc16bd7d1cda4a2a6a34001f 100644 (file)
@@ -17,7 +17,7 @@
 #else
 #define COUNT(cnt)
 #endif
-
 #define STACKRESET {curstack=0;stackdepth=0;}
 
 #define TYPEPANIC  {show_icmd_method();panic("Stack type mismatch");}
@@ -164,7 +164,9 @@ static void analyse_stack()
        int superblockend, repeat, deadcode;
        instruction *iptr = instr;
        basicblock *bptr, *tbptr;
-       s4  *s4ptr;
+       s4 *s4ptr;
+       void* *tptr;
+       xtable *ex;
        
        arguments_num = 0;
        new = stack;
@@ -290,6 +292,7 @@ static void analyse_stack()
                                b_index = bptr - block;
                                while (--len >= 0)  {
                                        opcode = iptr->opc;
+                                       iptr->target = NULL;
                                        switch (opcode) {
 
                                                /* pop 0 push 0 */
@@ -472,6 +475,9 @@ icmd_if_icmp_tail:
                                                                                /* iptr[1].opc = ICMD_NOP; */
                                                                                OP1_0(TYPE_INT);
                                                                                tbptr = block + block_index[iptr->op1];
+
+                                                                               iptr[0].target = (void *) tbptr;
+
                                                                                MARKREACHED(tbptr, copy);
                                                                                COUNT(count_pcmd_bra);
                                                                                break;
@@ -656,6 +662,9 @@ icmd_lconst_lcmp_tail:
                                                                                                iptr[2].opc = ICMD_NOP; */
                                                                                                OP1_0(TYPE_LNG);
                                                                                                tbptr = block + block_index[iptr->op1];
+
+                                                                                               iptr[0].target = (void *) tbptr;
+
                                                                                                MARKREACHED(tbptr, copy);
                                                                                                COUNT(count_pcmd_bra);
                                                                                                COUNT(count_pcmd_op);
@@ -858,6 +867,9 @@ icmd_lconst_lcmp_tail:
                                                        COUNT(count_pcmd_bra);
                                                        OP1_0(TYPE_ADR);
                                                        tbptr = block + block_index[iptr->op1];
+
+                                                       iptr[0].target = (void *) tbptr;
+
                                                        MARKREACHED(tbptr, copy);
                                                        break;
 
@@ -927,6 +939,9 @@ icmd_lconst_lcmp_tail:
 #endif
                                                        OP1_0(TYPE_INT);
                                                        tbptr = block + block_index[iptr->op1];
+
+                                                       iptr[0].target = (void *) tbptr;
+
                                                        MARKREACHED(tbptr, copy);
                                                        break;
 
@@ -935,6 +950,9 @@ icmd_lconst_lcmp_tail:
                                                case ICMD_GOTO:
                                                        COUNT(count_pcmd_bra);
                                                        tbptr = block + block_index[iptr->op1];
+
+                                                       iptr[0].target = (void *) tbptr;
+
                                                        MARKREACHED(tbptr, copy);
                                                        SETDST;
                                                        superblockend = true;
@@ -950,8 +968,19 @@ icmd_lconst_lcmp_tail:
                                                        MARKREACHED(tbptr, copy);
                                                        i = *s4ptr++;                          /* low     */
                                                        i = *s4ptr++ - i + 1;                  /* high    */
+
+                                                       tptr = DMNEW(void*, i+1);
+                                                       iptr->target = (void *) tptr;
+
+                                                       tptr[0] = (void *) tbptr;
+                                                       tptr++;
+
                                                        while (--i >= 0) {
                                                                tbptr = block + block_index[*s4ptr++];
+
+                                                               tptr[0] = (void *) tbptr;
+                                                               tptr++;
+
                                                                MARKREACHED(tbptr, copy);
                                                                }
                                                        SETDST;
@@ -967,8 +996,19 @@ icmd_lconst_lcmp_tail:
                                                        tbptr = block + block_index[*s4ptr++]; /* default */
                                                        MARKREACHED(tbptr, copy);
                                                        i = *s4ptr++;                          /* count   */
+
+                                                       tptr = DMNEW(void*, i+1);
+                                                       iptr->target = (void *) tptr;
+
+                                                       tptr[0] = (void *) tbptr;
+                                                       tptr++;
+
                                                        while (--i >= 0) {
                                                                tbptr = block + block_index[s4ptr[1]];
+
+                                                               tptr[0] = (void *) tbptr;
+                                                               tptr++;
+                                                               
                                                                MARKREACHED(tbptr, copy);
                                                                s4ptr += 2;
                                                                }
@@ -994,6 +1034,9 @@ icmd_lconst_lcmp_tail:
                                                        COUNT(count_pcmd_bra);
                                                        OP2_0(TYPE_INT);
                                                        tbptr = block + block_index[iptr->op1];
+                                                       
+                                                       iptr[0].target = (void *) tbptr;
+
                                                        MARKREACHED(tbptr, copy);
                                                        break;
 
@@ -1002,6 +1045,9 @@ icmd_lconst_lcmp_tail:
                                                        COUNT(count_pcmd_bra);
                                                        OP2_0(TYPE_ADR);
                                                        tbptr = block + block_index[iptr->op1];
+
+                                                       iptr[0].target = (void *) tbptr;
+
                                                        MARKREACHED(tbptr, copy);
                                                        break;
 
@@ -1201,6 +1247,9 @@ icmd_lcmp_if_tail:
                                                                                /* iptr[1].opc = ICMD_NOP; */
                                                                                OP2_0(TYPE_LNG);
                                                                                tbptr = block + block_index[iptr->op1];
+                       
+                                                                               iptr[0].target = (void *) tbptr;
+
                                                                                MARKREACHED(tbptr, copy);
                                                                                COUNT(count_pcmd_bra);
                                                                                break;
@@ -1342,6 +1391,9 @@ icmd_lcmp_if_tail:
                                                case ICMD_JSR:
                                                        OP0_1(TYPE_ADR);
                                                        tbptr = block + block_index[iptr->op1];
+
+                                                       iptr[0].target = (void *) tbptr;
+
                                                        tbptr->type=BBTYPE_SBR;
                                                        MARKREACHED(tbptr, copy);
                                                        OP1_0ANY;
@@ -1467,8 +1519,8 @@ builtin2:
                        else
                                count_block_stack[bptr->indepth]++;
                        len = bptr->icount;
-                       if (len <= 10) 
-                               count_block_size_distribution[len - 1]++;
+                       if (len < 10) 
+                               count_block_size_distribution[len]++;
                        else if (len <= 12)
                                count_block_size_distribution[10]++;
                        else if (len <= 14)
@@ -1658,11 +1710,14 @@ static char *jit_type[] = {
 
 static void show_icmd_method()
 {
-       int b, i, j, last;
+       int i, j, last;
        int deadcode;
        s4  *s4ptr;
        instruction *iptr;
-       
+       basicblock *bptr;
+       void **tptr;
+       xtable *ex;
+
        printf("\n");
        unicode_fprint(stdout, class->name);
        printf(".");
@@ -1672,11 +1727,11 @@ static void show_icmd_method()
        printf ("\n\nMax locals: %d\n", (int) maxlocals);
        printf ("Max stack:  %d\n", (int) maxstack);
 
-       printf ("Exceptions:\n");
-       for (i = 0; i < exceptiontablelength; i++) {
-               printf("    L%03d ... ", block_index[extable[i].startpc]);
-               printf("L%03d = ", block_index[extable[i].endpc]);
-               printf("L%03d\n", block_index[extable[i].handlerpc]);
+       printf ("Exceptions (Number: %d):\n", exceptiontablelength);
+       for (ex = extable; ex != NULL; ex = ex->down) {
+               printf("    L%03d ... ", ex->start->debug_nr );
+               printf("L%03d  = ", ex->end->debug_nr);
+               printf("L%03d\n", ex->handler->debug_nr);
                }
        
        printf ("Local Table:\n");
@@ -1735,19 +1790,20 @@ static void show_icmd_method()
                printf("\n");
                }
 
-       for (b = 0; b < block_count; b++)
-               if (block[b].flags != BBDELETED) {
-               deadcode = block[b].flags <= BBREACHED;
+       
+       for (bptr = block; bptr != NULL; bptr = bptr->next)
+               if (bptr->flags != BBDELETED) {
+               deadcode = bptr->flags <= BBREACHED;
                printf("[");
                if (deadcode)
                        for (j = maxstack; j > 0; j--)
                                printf(" ?  ");
                else
-                       print_stack(block[b].instack);
-               printf("] L%03d(%d):\n", b, block[b].pre_count);
-               iptr = block[b].iinstr;
-               i = iptr - instr;
-               for (last = i + block[b].icount; i < last; i++, iptr++) {
+                       print_stack(bptr->instack);
+               printf("] L%03d(%d - %d):\n", bptr->debug_nr, bptr->icount, bptr->pre_count);
+               iptr = bptr->iinstr;
+
+               for (i=0; i < bptr->icount; i++, iptr++) {
                        printf("[");
                        if (deadcode) {
                                for (j = maxstack; j > 0; j--)
@@ -1814,6 +1870,28 @@ static void show_icmd_method()
                                case ICMD_IINC:
                                        printf(" %d + %d", iptr->op1, iptr->val.i);
                                        break;
+
+                           case ICMD_IASTORE:
+                           case ICMD_SASTORE:
+                           case ICMD_BASTORE:
+                           case ICMD_CASTORE:
+                           case ICMD_LASTORE:
+                           case ICMD_DASTORE:
+                           case ICMD_FASTORE:
+                           case ICMD_AASTORE:
+
+                           case ICMD_IALOAD:
+                           case ICMD_SALOAD:
+                           case ICMD_BALOAD:
+                           case ICMD_CALOAD:
+                           case ICMD_LALOAD:
+                           case ICMD_DALOAD:
+                           case ICMD_FALOAD:
+                           case ICMD_AALOAD:
+                                       if (iptr->op1 != 0)
+                                               printf("(opt.)");
+                                       break;
+
                                case ICMD_RET:
                                case ICMD_ILOAD:
                                case ICMD_LLOAD:
@@ -1906,7 +1984,7 @@ static void show_icmd_method()
                                case ICMD_IF_LGE:
                                case ICMD_IF_LGT:
                                case ICMD_IF_LLE:
-                                       printf("(%d) L%03d", iptr->val.i, block_index[iptr->op1]);
+                                       printf("(%d) L%03d", iptr->val.i, ((basicblock *) iptr->target)->debug_nr);
                                        break;
                                case ICMD_JSR:
                                case ICMD_GOTO:
@@ -1926,25 +2004,39 @@ static void show_icmd_method()
                                case ICMD_IF_LCMPLE:
                                case ICMD_IF_ACMPEQ:
                                case ICMD_IF_ACMPNE:
-                                       printf(" L%03d", block_index[iptr->op1]);
+                                       printf(" L%03d", ((basicblock *) iptr->target)->debug_nr);
                                        break;
                                case ICMD_TABLESWITCH:
+
                                        s4ptr = iptr->val.a;
-                                       printf(" L%03d;", block_index[*s4ptr++]); /* default */
+                                       tptr = (void **) iptr->target;
+
+                                       printf(" L%03d;", ((basicblock *) *tptr)->debug_nr); 
+                                                                                   /* default */
+
+                                       s4ptr++;
+                                       tptr++;
+
                                        j = *s4ptr++;                               /* low     */
                                        j = *s4ptr++ - j;                           /* high    */
                                        while (j >= 0) {
-                                               printf(" L%03d", block_index[*s4ptr++]);
+                                               printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
+                                               tptr++;
                                                j--;
                                                }
                                        break;
                                case ICMD_LOOKUPSWITCH:
                                        s4ptr = iptr->val.a;
-                                       printf(" L%d", block_index[*s4ptr++]);   /* default */
-                                       j = *s4ptr++;                               /* count   */
+                                       tptr = (void **) iptr->target;
+
+                                       printf(" L%03d", ((basicblock *) *tptr)->debug_nr); 
+                                       s4ptr++;                                         /* default */
+                                       j = *s4ptr;                                      /* count   */
+                                       tptr++;
+
                                        while (--j >= 0) {
-                                               printf(" L%03d", block_index[s4ptr[1]]);
-                                               s4ptr += 2;
+                                               printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
+                                               tptr++;
                                                }
                                        break;
                                }
@@ -1953,15 +2045,26 @@ static void show_icmd_method()
 
                if (showdisassemble && (!deadcode)) {
                        printf("\n");
-                       i = block[b].mpc;
+                       i = bptr->mpc;
                        s4ptr = (s4 *) (method->mcode + dseglen + i);
-                       for (; i < block[b + 1].mpc; i += 4, s4ptr++) {
-                               disassinstr(*s4ptr, i); 
-                               }
-                       printf("\n");
-                       }
+
+                       if (bptr->next != NULL) {
+                               for (; i < bptr->next->mpc; i += 4, s4ptr++) {
+                                       disassinstr(*s4ptr, i); 
+                                   }
+                               printf("\n");
+                           }
+                       else {
+                               for (; s4ptr < (s4 *) (method->mcode + method->mcodelength); i += 4, s4ptr++) {
+                                       disassinstr(*s4ptr, i); 
+                                   }
+                               printf("\n");
+                           }
+                   }
        }
-       i = block[b].mpc;
+
+       /*
+       i = bptr->mpc;
        s4ptr = (s4 *) (method->mcode + dseglen + i);
        if (showdisassemble && (s4ptr < (s4 *) (method->mcode + method->mcodelength))) {
                printf("\n");
@@ -1970,6 +2073,7 @@ static void show_icmd_method()
                        }
                printf("\n");
                }
+       */
 }
 
 
diff --git a/main.c b/main.c
index fd2ad97941ffa007af0a2046e56a38c4530cc188..e47a1098c3e67cfb5c6701dcb0bd3ea3e26d3f17 100644 (file)
--- a/main.c
+++ b/main.c
@@ -17,7 +17,7 @@
                 Mark Probst         EMAIL: cacao@complang.tuwien.ac.at
                         Philipp Tomsich     EMAIL: cacao@complang.tuwien.ac.at
 
-       Last Change: $Id: main.c 123 1999-01-28 19:48:49Z phil $
+       Last Change: $Id: main.c 132 1999-09-27 15:54:42Z chris $
 
 *******************************************************************************/
 
@@ -89,6 +89,7 @@ void **stackbottom = 0;
 #define OPT_GC1         22
 #define OPT_GC2         23
 #endif
+#define OPT_OLOOP       24
 
 struct {char *name; bool arg; int value;} opts[] = {
        {"classpath",   true,   OPT_CLASSPATH},
@@ -121,6 +122,7 @@ struct {char *name; bool arg; int value;} opts[] = {
        {"gc1",         false,  OPT_GC1},
        {"gc2",         false,  OPT_GC2},
 #endif
+       {"oloop",       false,  OPT_OLOOP},
        {NULL,  false, 0}
 };
 
@@ -198,6 +200,7 @@ static void print_usage()
        printf ("          -log logfile ......... specify a name for the logfile\n");
        printf ("          -c(heck)b(ounds) ..... don't check array bounds\n");
        printf ("                  s(ync) ....... don't check for synchronization\n");
+       printf ("          -oloop ............... optimize array accesses in loops\n"); 
        printf ("          -l ................... don't start the class after loading\n");
        printf ("          -all ................. compile all methods, no execution\n");
 #ifdef OLD_COMPILER
@@ -675,6 +678,10 @@ int main(int argc, char **argv)
                        }
                        break;
                        
+               case OPT_OLOOP:
+                       opt_loops = true;
+                       break;
+
                default:
                        print_usage();
                        exit(10);
index 2479c5a6fb8b61d0b7ff052121662695cdbea5a8..6a49b83e425d10c0366485df9c09f00791034dda 100644 (file)
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4 from Makefile.am
+# Makefile.in generated automatically by automake 1.3 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -11,7 +11,7 @@
 # PARTICULAR PURPOSE.
 
 
-SHELL = @SHELL@
+SHELL = /bin/sh
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -32,7 +32,7 @@ mandir = @mandir@
 includedir = @includedir@
 oldincludedir = /usr/include
 
-DESTDIR =
+DISTDIR =
 
 pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -46,7 +46,7 @@ AUTOMAKE = @AUTOMAKE@
 AUTOHEADER = @AUTOHEADER@
 
 INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 transform = @program_transform_name@
@@ -71,8 +71,8 @@ SYSDEP_DIR = @SYSDEP_DIR@
 THREAD_OBJ = @THREAD_OBJ@
 VERSION = @VERSION@
 
-EXTRA_DIST = asmpart.c calling.doc defines.h disass.c       native-math.h ngen.c ngen.h threads.h types.h
-
+EXTRA_DIST = asmpart.c calling.doc defines.h disass.c \
+            native-math.h ngen.c ngen.h threads.h types.h
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = ../config.h
 CONFIG_CLEAN_FILES = 
@@ -82,13 +82,14 @@ DIST_COMMON =  Makefile.am Makefile.in
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = tar
-GZIP_ENV = --best
-all: all-redirect
+GZIP = --best
+all: Makefile
+
 .SUFFIXES:
-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-       cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps mips/Makefile
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu mips/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -101,75 +102,67 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = mips
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu mips/Makefile
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
-         if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
-         else \
-           test -f $(distdir)/$$file \
-           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
-           || cp -p $$d/$$file $(distdir)/$$file || :; \
-         fi; \
+         test -f $(distdir)/$$file \
+         || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+         || cp -p $$d/$$file $(distdir)/$$file; \
        done
-info-am:
-info: info-am
-dvi-am:
-dvi: dvi-am
-check-am: all-am
-check: check-am
-installcheck-am:
-installcheck: installcheck-am
-install-exec-am:
-install-exec: install-exec-am
-
-install-data-am:
-install-data: install-data-am
-
-install-am: all-am
-       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-install: install-am
-uninstall-am:
-uninstall: uninstall-am
-all-am: Makefile
-all-redirect: all-am
+info:
+dvi:
+check: all
+       $(MAKE)
+installcheck:
+install-exec: 
+       @$(NORMAL_INSTALL)
+
+install-data: 
+       @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+       @:
+
+uninstall: 
+
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+       $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
 installdirs:
 
 
 mostlyclean-generic:
+       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
 
 clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
-       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f Makefile $(DISTCLEANFILES)
        -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
 
 maintainer-clean-generic:
-mostlyclean-am:  mostlyclean-generic
-
-mostlyclean: mostlyclean-am
-
-clean-am:  clean-generic mostlyclean-am
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean:  mostlyclean-generic
 
-clean: clean-am
+clean:  clean-generic mostlyclean
 
-distclean-am:  distclean-generic clean-am
+distclean:  distclean-generic clean
+       -rm -f config.status
 
-distclean: distclean-am
-
-maintainer-clean-am:  maintainer-clean-generic distclean-am
+maintainer-clean:  maintainer-clean-generic distclean
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
-maintainer-clean: maintainer-clean-am
-
-.PHONY: tags distdir info-am info dvi-am dvi check check-am \
-installcheck-am installcheck install-exec-am install-exec \
-install-data-am install-data install-am install uninstall-am uninstall \
-all-redirect all-am all installdirs mostlyclean-generic \
-distclean-generic clean-generic maintainer-clean-generic clean \
-mostlyclean distclean maintainer-clean
+.PHONY: tags distdir info dvi installcheck install-exec install-data \
+install uninstall all installdirs mostlyclean-generic distclean-generic \
+clean-generic maintainer-clean-generic clean mostlyclean distclean \
+maintainer-clean
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
index 8c8dc9f0eaa637f1c5fb5420f269874b149b4a97..e6422d65310d295fa9c66b6a075551e008a76740 100644 (file)
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4 from Makefile.am
+# Makefile.in generated automatically by automake 1.3 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -11,7 +11,7 @@
 # PARTICULAR PURPOSE.
 
 
-SHELL = @SHELL@
+SHELL = /bin/sh
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -32,7 +32,7 @@ mandir = @mandir@
 includedir = @includedir@
 oldincludedir = /usr/include
 
-DESTDIR =
+DISTDIR =
 
 pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -46,7 +46,7 @@ AUTOMAKE = @AUTOMAKE@
 AUTOHEADER = @AUTOHEADER@
 
 INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 transform = @program_transform_name@
@@ -73,11 +73,14 @@ VERSION = @VERSION@
 
 noinst_LIBRARIES = libmm_new.a libmm_old.a
 
-libmm_new_a_SOURCES = allocator2.c allocator.h                       bitmap2.c bitmap2.h                     heap2.c                 lifespan.c lifespan.h                   mm.h
-
+libmm_new_a_SOURCES = allocator2.c allocator.h \
+                     bitmap2.c bitmap2.h \
+                     heap2.c \
+                     lifespan.c lifespan.h \
+                     mm.h
 libmm_old_a_SOURCES = heap.old.c
 
-INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/@SYSDEP_DIR@
+INCLUDES=-I$(top_srcdir) -I$(top_srcdir)/@SYSDEP_DIR@
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = ../config.h
 CONFIG_CLEAN_FILES = 
@@ -94,26 +97,28 @@ libmm_old_a_LIBADD =
 libmm_old_a_OBJECTS =  heap.old.o
 AR = ar
 CFLAGS = @CFLAGS@
-COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
 DIST_COMMON =  Makefile.am Makefile.in
 
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = tar
-GZIP_ENV = --best
+GZIP = --best
+DEP_FILES =  .deps/allocator2.P .deps/bitmap2.P .deps/heap.old.P \
+.deps/heap2.P .deps/lifespan.P
 SOURCES = $(libmm_new_a_SOURCES) $(libmm_old_a_SOURCES)
 OBJECTS = $(libmm_new_a_OBJECTS) $(libmm_old_a_OBJECTS)
 
-all: all-redirect
+all: Makefile $(LIBRARIES)
+
 .SUFFIXES:
 .SUFFIXES: .S .c .o .s
-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-       cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps mm/Makefile
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu mm/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -127,9 +132,6 @@ distclean-noinstLIBRARIES:
 
 maintainer-clean-noinstLIBRARIES:
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -159,12 +161,8 @@ libmm_old.a: $(libmm_old_a_OBJECTS) $(libmm_old_a_DEPENDENCIES)
 tags: TAGS
 
 ID: $(HEADERS) $(SOURCES) $(LISP)
-       list='$(SOURCES) $(HEADERS)'; \
-       unique=`for i in $$list; do echo $$i; done | \
-         awk '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
        here=`pwd` && cd $(srcdir) \
-         && mkid -f$$here/ID $$unique $(LISP)
+         && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
 
 TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
        tags=; \
@@ -190,84 +188,102 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = mm
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu mm/Makefile
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
-         if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
-         else \
-           test -f $(distdir)/$$file \
-           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
-           || cp -p $$d/$$file $(distdir)/$$file || :; \
-         fi; \
+         test -f $(distdir)/$$file \
+         || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+         || cp -p $$d/$$file $(distdir)/$$file; \
        done
-info-am:
-info: info-am
-dvi-am:
-dvi: dvi-am
-check-am: all-am
-check: check-am
-installcheck-am:
-installcheck: installcheck-am
-install-exec-am:
-install-exec: install-exec-am
-
-install-data-am:
-install-data: install-data-am
-
-install-am: all-am
-       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-install: install-am
-uninstall-am:
-uninstall: uninstall-am
-all-am: Makefile $(LIBRARIES)
-all-redirect: all-am
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+
+maintainer-clean-depend:
+       -rm -rf .deps
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).P -c $<
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).p -c $<
+       @-sed -e 's/^\([^:]*\)\.o:/\1.lo \1.o:/' \
+         < .deps/$(*F).p > .deps/$(*F).P
+       @-rm -f .deps/$(*F).p
+info:
+dvi:
+check: all
+       $(MAKE)
+installcheck:
+install-exec: 
+       @$(NORMAL_INSTALL)
+
+install-data: 
+       @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+       @:
+
+uninstall: 
+
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+       $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
 installdirs:
 
 
 mostlyclean-generic:
+       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
 
 clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
-       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f Makefile $(DISTCLEANFILES)
        -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
 
 maintainer-clean-generic:
-mostlyclean-am:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
-               mostlyclean-tags mostlyclean-generic
-
-mostlyclean: mostlyclean-am
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
+               mostlyclean-tags mostlyclean-depend mostlyclean-generic
 
-clean-am:  clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
-               mostlyclean-am
+clean:  clean-noinstLIBRARIES clean-compile clean-tags clean-depend \
+               clean-generic mostlyclean
 
-clean: clean-am
+distclean:  distclean-noinstLIBRARIES distclean-compile distclean-tags \
+               distclean-depend distclean-generic clean
+       -rm -f config.status
 
-distclean-am:  distclean-noinstLIBRARIES distclean-compile \
-               distclean-tags distclean-generic clean-am
-
-distclean: distclean-am
-
-maintainer-clean-am:  maintainer-clean-noinstLIBRARIES \
+maintainer-clean:  maintainer-clean-noinstLIBRARIES \
                maintainer-clean-compile maintainer-clean-tags \
-               maintainer-clean-generic distclean-am
+               maintainer-clean-depend maintainer-clean-generic \
+               distclean
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
-maintainer-clean: maintainer-clean-am
-
 .PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
 clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
 mostlyclean-compile distclean-compile clean-compile \
 maintainer-clean-compile tags mostlyclean-tags distclean-tags \
-clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
-check-am installcheck-am installcheck install-exec-am install-exec \
-install-data-am install-data install-am install uninstall-am uninstall \
-all-redirect all-am all installdirs mostlyclean-generic \
-distclean-generic clean-generic maintainer-clean-generic clean \
-mostlyclean distclean maintainer-clean
+clean-tags maintainer-clean-tags distdir mostlyclean-depend \
+distclean-depend clean-depend maintainer-clean-depend info dvi \
+installcheck install-exec install-data install uninstall all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/narray/analyze.c b/narray/analyze.c
new file mode 100644 (file)
index 0000000..42444c5
--- /dev/null
@@ -0,0 +1,3564 @@
+/* analyze.c *******************************************************************
+
+        Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+        See file COPYRIGHT for information on usage and disclaimer of warranties.
+
+        Contains the functions which perform the bound check removals. With 
+               the loops identified, these functions scan the code for array accesses
+               that take place in loops and try to guarantee that their bounds are
+               never violated. The function to call is optimize_loops().
+
+        Authors: Christopher Kruegel      EMAIL: cacao@complang.tuwien.ac.at
+
+        Last Change: 1998/17/02
+
+*******************************************************************************/
+#ifdef LOOP_DEBUG
+
+/*     Test functions -> will be removed in final release
+*/
+void show_trace(struct Trace *trace)
+{
+       if (trace != NULL) {
+               switch (trace->type) {
+               case TRACE_IVAR:
+                       printf("int-var");
+                       printf("\nNr.:\t%d", trace->var);
+                       printf("\nValue:\t%d", trace->constant);
+                       break;
+      
+               case TRACE_AVAR:
+                       printf("object-var");
+                       printf("\nNr.:\t%d", trace->var);
+                       break;
+      
+               case TRACE_ALENGTH:
+                       printf("array-length");
+                       printf("\nNr.:\t%d", trace->var);
+                       printf("\nValue:\t%d", trace->constant);
+                       break;
+
+               case TRACE_ICONST:
+                       printf("int-const");
+                       printf("\nValue:\t%d", trace->constant);
+                       break;
+      
+               case TRACE_UNKNOWN:
+                       printf("unknown");
+                       break;
+                       }
+               }
+       else
+               printf("Trace is null");
+       
+       printf("\n");
+}
+void show_change(struct Changes *c)
+{
+       printf("*** Changes ***\n");
+       if (c != NULL)
+               printf("Lower/Upper Bound:\t%d/%d\n", c->lower_bound, c->upper_bound);
+       else
+               printf("Unrestricted\n");
+}
+show_varinfo(struct LoopVar *lv)
+{
+       printf("   *** Loop Info ***\n");
+       printf("Value:\t%d\n", lv->value);
+       printf("Static:\t\t%d/%d\n", lv->static_l, lv->static_u);
+       printf("D-Valid:\t%d/%d\n", lv->dynamic_l_v, lv->dynamic_u_v);
+       printf("Dynamic\t\t%d/%d\n", lv->dynamic_l, lv->dynamic_u);
+}
+void show_right_side()
+{
+       int i;
+       printf("\n   *** Head ***   \nType:\t");
+       show_trace(c_rightside);
+
+       printf("\n   *** Nested Loops: ***\n");
+       for (i=0; i<block_count; ++i) 
+               printf("%d\t", c_nestedLoops[i]);
+       printf("\n");
+
+       printf("\n   *** Hierarchie: ***\n");   
+       for (i=0; i<block_count; ++i) 
+               printf("%d\t", c_hierarchie[i]);
+       printf("\n");
+       
+
+       printf("\n   *** Current Loop ***\n");
+       for (i=0; i<block_count; ++i)
+           printf("%d\t", c_current_loop[i]);
+       printf("\n");
+}
+void resultPass3()
+{
+       int i;
+       struct LoopContainer *lc = c_allLoops;
+  
+       printf("\n\n****** PASS 3 ******\n\n");
+  
+       while (lc != NULL) {
+               printf("Loop Analysis:\n");
+               printf("Optimize:\t%d\n", lc->toOpt);
+               printf("Modified Vars: ");
+               /*
+               for (i=0; i<lc->num_vars; ++i)
+                 printf("%d ", lc->vars[i]);
+               printf("\n\n");
+               */
+               lc = lc->next;
+               }
+
+       printf("\nNested Loops:\n");
+       for (i=0; i<block_count; ++i)
+           printf("%d ", c_nestedLoops[i]);
+       printf("\n");
+       for (i=0; i<block_count; ++i) 
+               printf("%d ", c_hierarchie[i]);
+       printf("\n");
+       fflush(stdout);
+}
+void show_tree(struct LoopContainer *lc, int tabs) 
+{
+       int cnt;
+
+       while (lc != NULL) {
+               for (cnt = 0; cnt < tabs; ++cnt)
+                       printf("  ");
+               printf("%d\n", lc->loop_head);
+
+               show_tree(lc->tree_down, tabs+1);
+
+               lc = lc->tree_right;
+       }
+}
+
+#endif
+
+#ifdef STATISTICS
+
+void show_loop_statistics()
+{
+       printf("\n\n****** LOOP STATISTICS ****** \n\n");
+       if (c_stat_or) 
+           printf("Optimization cancelled by or\n");
+       else if (c_stat_exception)
+           printf("Optimization cancelled by exception\n");
+       else {
+               printf("Number of array accesses:\t%d\n", c_stat_array_accesses);
+               if (c_stat_array_accesses) {
+                       printf("\nFully optimized:\t%d\n", c_stat_full_opt);
+                       printf("Not optimized:\t\t%d\n", c_stat_no_opt);
+                       printf("Upper optimized:\t%d\n", c_stat_upper_opt);
+                       printf("Lower optimized:\t%d\n", c_stat_lower_opt);
+                       }
+               }
+}
+void show_procedure_statistics()
+{
+       printf("\n\n****** PROCEDURE STATISTICS ****** \n\n");
+       printf("Number of loops:\t\t%d\n", c_stat_num_loops);
+       printf("Number of array accesses:\t%d\n", c_stat_sum_accesses);
+       if (c_stat_sum_accesses) {
+               printf("\nFully optimized:\t%d\n", c_stat_sum_full);
+               printf("Not optimized:\t\t%d\n", c_stat_sum_no);
+               printf("Upper optimized:\t%d\n", c_stat_sum_upper);
+               printf("Lower optimized:\t%d\n", c_stat_sum_lower);
+               }
+       printf("Opt. cancelled by or:\t\t%d\n", c_stat_sum_or);
+       printf("Opt. cancelled by exception:\t%d\n", c_stat_sum_exception);
+}
+
+#endif
+
+
+/*     This function is used to merge two loops with the same header together.
+       A simple merge sort of the lists nodes of both loops is performed.
+*/
+void analyze_merge(struct LoopContainer *l1, struct LoopContainer *l2)
+{
+       struct LoopElement *start, *last, *le1, *le2; 
+       /* start and last are pointers to the newly built list, le1 and le2 step    */
+       /* step through the lists, that have to be merged.                          */
+
+       le1 = l1->nodes;
+       le2 = l2->nodes;
+
+       /* start a simple merge sort of the nodes of both loops. These lists are    */
+       /* already sorted, so merging is easy.                                      */
+       if (le1->node < le2->node) {
+               start = last = le1;
+               le1 = le1->next;
+               }
+       else if (le1->node == le2->node) {
+               start = last = le1;
+               le1 = le1->next;
+               le2 = le2->next;
+               }
+       else {
+               start = last = le2;
+               le2 = le2->next;
+               }
+
+       /* while the first loop != NULL, depending of the first element of second   */
+       /* loop, add new node to result list                                        */
+       while (le1 != NULL) {
+
+               if (le2 == NULL) {
+                       last->next = le1;
+                       break;
+                       }
+               if (le1->node < le2->node) {
+                       last->next = le1;
+                       le1 = le1->next;
+                       }
+               else if (le1->node == le2->node) {
+                       last->next = le1;
+                       le1 = le1->next;
+                       le2 = le2->next;
+                       last = last->next;
+                       }
+               else {
+                       last->next = le2;
+                       le2 = le2->next;
+                       last = last->next;
+                       }
+               }
+
+       last->next = le2;                       
+}
+
+
+/*     This function is used to merge loops with the same header node to a single 
+       one. O(n^2) of number of loops. This merginig is necessary, because the loop
+       finding algorith sometimes (eg. when loopbody ends with a if-else construct)
+       reports a single loop as two loops with the same header node.
+*/
+void analyze_double_headers()
+{
+       int toCheck;
+       struct LoopContainer *t1, *t2, *t3;
+
+       t1 = c_allLoops;
+
+       while (t1 != NULL)      {                       /* for all loops do                                                     */
+               toCheck = t1->loop_head;        /* get header node                                                      */
+               t2 = t1->next;
+
+               while (t2 != NULL) {            /* compare it to headers of rest                        */
+                       if (t2->loop_head == toCheck) {
+
+                               /* found overlapping loops -> merge them together                               */
+                               /* printf("C_INFO: found overlapping loops - merging");         */
+                               analyze_merge(t1, t2);
+                               
+                               /* remove second loop from the list     of all loops                            */
+                               t3 = t1;       
+                               while (t3->next != t2)
+                                       t3 = t3->next;
+                               t3->next = t2->next;
+                               }
+                       t2 = t2->next;
+                   }
+
+               t1 = t1->next;
+           }
+}
+
+
+/* After the hierarchie of loops has been built, we have to insert the exceptions
+   into this tree. The exception ex is inserted into the subtree pointed to by
+   LoopContainer lc.
+*/
+void insert_exception(struct LoopContainer *lc, xtable *ex)
+{
+       struct LoopContainer *temp;
+       struct LoopElement *le;
+
+#ifdef LOOP_DEBUG
+       /* printf("insert_exception called with %d-%d and loop %d\n", ex->start->debug_nr, ex->end->debug_nr, lc->loop_head); */
+#endif
+       
+       /* if child node is reached immediately insert the exception into the tree  */
+       if (lc->tree_down == NULL) {
+               ex->next = lc->exceptions;
+               lc->exceptions = ex;
+           }
+       else {
+       /* if we are inside the tree, there are two possibilities:                  */
+       /* 1. the exception is inside a nested loop or                              */
+       /* 2. in the loop body of the current loop                                  */
+
+               /* check all children (= nested loops)                                  */
+               temp = lc->tree_down;
+               
+               while (temp != NULL) {
+                       
+                       le = temp->nodes;
+                       while (le != NULL) {
+
+#ifdef LOOP_DEBUG
+                               printf("%d.%d\n", le->node, block_index[ex->startpc]);
+#endif
+                               /* if the start of the exception is part of the loop, the whole */
+                               /* exception must be part of the loop                           */
+                               if (le->node == block_index[ex->startpc])
+                                       break;
+                               le = le->next;
+                           }
+                       
+                       /* Exception is part of a nested loop (Case 1) -> insert it there   */
+                       if (le != NULL) {
+                               insert_exception(temp, ex);
+                               return;
+                           }
+                       else if ((temp->loop_head >= block_index[ex->startpc]) && (temp->loop_head < block_index[ex->endpc])) {
+                               
+                               /* optimization: if nested loop is part of the exception, the   */
+                               /* exception cannot be part of a differnet nested loop.         */
+                               ex->next = lc->exceptions;
+                               lc->exceptions = ex;
+                               return;
+                           }
+                       else
+                               temp = temp->tree_right;
+                   }
+                   
+               /* Exception is not contained in any nested loop (Case 2)               */
+               if (temp == NULL) {
+                       ex->next = lc->exceptions;
+                       lc->exceptions = ex;
+                   }
+           } 
+}
+
+
+/*     This function builds a loop hierarchie. The header node of the innermost loop,
+       each basic block belongs to, is stored in the array c_nestedLoops. The array
+       c_hierarchie stores the relationship between differnt loops in as follows: 
+    Each loop, that is a nested loop, stores its direct surrounding loop as a 
+    parent. Top level loops have no parents.
+*/
+void analyze_nested()
+{
+       /* i/count/tmp are counters                                                 */
+       /* toOverwrite is used while loop hierarchie is built (see below)           */
+       int i, count, header, toOverwrite, tmp, len;
+
+       /* first/last are used during topological sort to build ordered loop list   */
+       struct LoopContainer *first, *last, *start, *t, *temp;
+
+       /* Used to step through all nodes of a loop.                                */
+       struct LoopElement *le; 
+
+       /* init global structures                                                   */
+       c_nestedLoops = DMNEW(int, block_count);
+       c_hierarchie = DMNEW(int, block_count);         
+       for (i=0; i<block_count; ++i) {
+               c_nestedLoops[i] = -1;
+               c_hierarchie[i] = -1;
+           }
+
+       /* if there are no optimizable loops -> return                              */
+       if (c_allLoops == NULL)
+               return;
+
+       temp = c_allLoops;
+       while (temp != NULL) {                                  /* for all loops, do                            */
+               header = temp->loop_head;
+
+               /* toOverwrite is number of current parent loop (-1 if none)                    */
+               toOverwrite = c_nestedLoops[header];    
+
+               c_hierarchie[header] = toOverwrite;
+
+               if (toOverwrite == header)                      /* check for loops with same header */
+                       printf("C_ERROR: Loops have same header\n");
+
+               le = temp->nodes;
+               while (le != NULL) {                            /* for all loop nodes, do                       */
+                       tmp = c_nestedLoops[le->node];
+
+                   /* if node is part of parent loop -> overwrite it with nested           */
+                       if (tmp == toOverwrite)
+                               c_nestedLoops[le->node] = header;
+                       else {
+                               c_hierarchie[tmp] = header;
+#ifdef LOOP_DEBUG
+                               /* printf("set head of %d to %d", tmp, header);                 */
+#endif
+                           }
+
+                       le = le->next;
+                       }
+
+               temp = temp->next;
+               }
+
+       /* init root of hierarchie tree                                             */
+       root = DMNEW(struct LoopContainer, 1);
+       LoopContainerInit(root, -1);
+
+    /* obtain parent pointer and build hierarchie tree                          */
+    start = c_allLoops;    
+    while (start != NULL) {
+               
+               /* look for parent of loop pointed at by start                          */
+               first = c_allLoops;
+               while (first != NULL) {
+
+                       /* the parent of the loop, pointed at by start has been found       */
+                       if (first->loop_head == c_hierarchie[start->loop_head]) {
+#ifdef LOOP_DEBUG
+                               /* printf("set parent to pointer\n");                           */
+#endif
+
+                               start->parent = first;
+                               start->tree_right = first->tree_down;
+                               first->tree_down = start;
+
+                               break;
+                           }
+                       first = first->next;
+                   }
+
+               /* no parent loop found, set parent to root                             */
+               if (first == NULL) {
+#ifdef LOOP_DEBUG
+                       /* printf("set parent to root\n");                                  */
+#endif
+                       start->parent = root;
+                       start->tree_right = root->tree_down;
+                       root->tree_down = start;                
+                   }
+               /* if a parent exists, increase this nodes indegree                     */
+               else
+                       start->parent->in_degree += 1;
+
+               start = start->next;
+           }
+
+       /* insert exceptions into tree                                              */
+#ifdef LOOP_DEBUG
+       printf("--- Showing tree ---\n");
+       show_tree(root, 0);
+       printf(" --- End ---\n");
+#endif
+       for (len = 0; len < exceptiontablelength; ++len) 
+               insert_exception(root, extable + len);
+
+
+       /* determine sequence of loops for optimization by topological sorting them */
+
+       /* init queue                                                               */
+       start = NULL;
+       temp = c_allLoops;
+       while (temp != NULL) {
+
+               /* a loops with indegree == 0 are pushed onto the stack                 */
+               if (temp->in_degree == 0) {
+                       t = temp->next;
+                       temp->next = start;
+                       start = temp;
+                       }
+               else 
+                       t = temp->next;
+                   
+               temp = t;
+               }
+
+       /* sort loops                                                               */
+       first = last = start;
+       start = start->next;
+
+       if (last == NULL) {
+               printf("C_ERROR: loops are looped\n");
+               exit(-1);
+           }
+
+       /* pop each node from the stack and decrease its parents indegree by one    */
+       /* when the parents indegree reaches zero, push it onto the stack as well   */
+       if ((last->parent != root) && (--last->parent->in_degree == 0)) {
+               last->parent->next = start;
+               start = last->parent;
+               }
+       while (start != NULL) {
+
+               last->next = start;
+
+               start = start->next;
+               last = last->next;
+               
+               if ((last->parent != root) && (--last->parent->in_degree == 0)) {
+                       last->parent->next = start;
+                       start = last->parent;
+                       }
+               }
+
+       last->next = NULL;
+       c_allLoops = first;
+
+#ifdef LOOP_DEBUG
+       printf("*** Hierarchie Results \n");
+       while (first != NULL) {
+               printf("%d ", first->loop_head);
+               first = first->next;
+           }
+       printf("\n");
+       fflush(stdout);
+#endif 
+}
+
+/*     This function is used to add variables that occur as index variables in
+       array accesses (ARRAY_INDEX) or as variables, that change their value (VAR_MOD)
+       to the list of interesting vars (c_loopvars) for the current loop.
+*/
+void add_to_vars(int var, int type, int direction)
+{
+       struct LoopVar *lv;     
+
+       /* printf("Added to vars %d %d %d\n", var, type, direction);                            */
+       lv = c_loopvars;
+       while (lv != NULL) {                    /* check if var has been previously added       */
+               if (lv->value == var) {
+                       if (type == ARRAY_INDEX)
+                               lv->index = 1;                          /* var is used as index                     */
+                       else if (type == VAR_MOD) {
+                               lv->modified = 1;                       /* var is used in assignment            */
+                               switch (direction) {            /* how was var modified ?                       */
+                               case D_UP:
+                                       lv->static_u = 0;               /* incremented, no static upper         */
+                                       break;                                  /* bound can be guaranteeed                     */
+                               case D_DOWN:
+                                       lv->static_l = 0;               /* decremented, no static lower         */
+                                       break;                                  /* bound can be guaranteeed                     */
+                               case D_UNKNOWN:
+                                       lv->static_u = lv->static_l = 0;
+                                       break;                                  /* no info at all                                       */
+                               default:
+                                       printf("C_ERROR: unknown direction\n");
+                                       break;
+                                       }
+                               }
+                       return;
+                       }
+               lv = lv->next;
+               }
+
+       /* variable is not found in list -> add variable to list                                        */
+       lv = DNEW(struct LoopVar);
+
+       lv->value = var;
+       if (type == ARRAY_INDEX) {
+               lv->index = 1;
+               lv->static_u = lv->static_l = 1;        /* array index -> var not modified      */
+               }
+       else if (type == VAR_MOD) {
+               lv->modified = 1;
+               switch (direction) {                            /* var is used in assignment -> set     */
+               case D_UP:                                                      /* proper static bounds                         */
+                       lv->static_u = 0; lv->static_l = 1;
+                       break;
+               case D_DOWN:
+                       lv->static_u = 1; lv->static_l = 0;
+                       break;
+               case D_UNKNOWN:
+                       lv->static_u = lv->static_l = 0;
+                       break;
+               default:
+                       printf("C_ERROR: unknown direction\n");
+                       break;
+                       }
+               }
+       
+       /* !! strange 
+          lv->modified = 0; 
+          */
+
+       /* no dynamic bounds have been determined so far                                                        */
+       lv->dynamic_l = lv->dynamic_l_v = lv->dynamic_u = lv->dynamic_u_v = 0;
+
+       lv->next = c_loopvars;                                  /* add var to list                                      */
+       c_loopvars = lv;
+}
+
+/*     This function checks, whether a given loop with header node contains array
+       accesses. If so, it returns 1, else it returns 0 and the loops needs no
+       further consideration in the optimization process. When array accesses are 
+       found, a list of all variables, that are used as array index, is built and 
+       stored in c_loopvars. For all variables (integer), which values are changed, 
+       a flag in c_var_modified is set.
+*/
+int analyze_for_array_access(int node)
+{
+       basicblock bp;
+       instruction *ip;
+       int ic, i, j, access;
+       struct depthElement *d;
+       struct Trace *t;
+
+       if (c_toVisit[node] > 0) {                      /* node has not been visited yet                */
+               c_toVisit[node] = 0;
+   
+               bp = block[node];                               /* prepare an instruction scan                  */
+               ip = bp.iinstr;
+               ic = bp.icount;
+
+               access = 0;                                             /* number of array accesses in loop             */
+
+               for (i=0; i<ic; ++i, ++ip) {    /* for each instruction, check opcode   */
+                       switch (ip->opc) {
+                       case ICMD_IASTORE:                      /* array store                                                  */
+                       case ICMD_LASTORE:          
+                       case ICMD_FASTORE:          
+                       case ICMD_DASTORE:          
+                       case ICMD_AASTORE:          
+                       case ICMD_BASTORE:          
+                       case ICMD_CASTORE:          
+                       case ICMD_SASTORE:
+                               t = tracing(&bp, i-1, 1);       /* try to identify index variable       */
+
+                               if (t->type == TRACE_IVAR) {
+                                       /* if it is a variable, add it to list of index variables       */
+                                       add_to_vars(t->var, ARRAY_INDEX, D_UNKNOWN);
+                                       access++;                               
+                               }
+                               else if (t->type == TRACE_ICONST)
+                                       access++;
+                               break;
+      
+                       case ICMD_IALOAD:                               /* array load                                           */
+                   case ICMD_LALOAD:       
+                       case ICMD_FALOAD:
+                       case ICMD_DALOAD:
+                       case ICMD_AALOAD:
+                       case ICMD_BALOAD:
+                       case ICMD_CALOAD:
+                       case ICMD_SALOAD:
+                               t = tracing(&bp, i-1, 0);       /* try to identify index variable       */
+               
+                               if (t->type == TRACE_IVAR) {
+                                       /* if it is a variable, add it to list of index variables       */
+                                       add_to_vars(t->var, ARRAY_INDEX, D_UNKNOWN);
+                                       access++;
+                                       }
+                               else if (t->type == TRACE_ICONST)
+                                       access++;
+                               break;
+
+                       case ICMD_ISTORE:                               /* integer store                                        */
+                               c_var_modified[ip->op1] = 1;
+
+                               /* try to find out, how it was modified                                                 */
+                               t = tracing(&bp, i-1, 0);       
+                               if (t->type == TRACE_IVAR) {
+                                       if ((t->constant > 0) && (t->var == ip->op1))
+                                               /* a constant was added to the same var                                 */
+                                               add_to_vars(t->var, VAR_MOD, D_UP);
+                                       else if (t->var == ip->op1)     
+                                               /* a constant was subtracted from the same var                  */
+                                               add_to_vars(t->var, VAR_MOD, D_DOWN);
+                                       else
+                                               add_to_vars(t->var, VAR_MOD, D_UNKNOWN);
+                                       }
+                               else
+                                       add_to_vars(ip->op1, VAR_MOD, D_UNKNOWN);
+                               break;
+
+                       case ICMD_IINC:                                 /* simple add/sub of a constant         */
+                               c_var_modified[ip->op1] = 1;
+               
+                               if (ip->val.i > 0)
+                                       add_to_vars(ip->op1, VAR_MOD, D_UP);
+                               else
+                                       add_to_vars(ip->op1, VAR_MOD, D_DOWN);
+                               break;
+
+                       case ICMD_LSTORE:
+                       case ICMD_FSTORE:
+                       case ICMD_DSTORE:
+                       case ICMD_ASTORE:
+                               c_var_modified[ip->op1] = 1;
+                               break;
+
+                       default:
+                               }
+                       }
+
+               d = c_dTable[node];
+               while (d != NULL) {                                     /* check all successors of block        */
+                       access += analyze_for_array_access(d->value);
+                       d = d->next;
+                       }
+
+               return access;
+               }
+       else
+               return 0;
+}
+
+/*     This function scans the exception graph structure to find modifications of
+       array index variables of the current loop. If any modifications are found,
+       1 is returned, else 0.
+*/
+int quick_scan(int node)
+{
+       basicblock bp;
+       instruction *ip;
+       int count, i;
+       struct LoopVar *lv;
+       struct depthElement *d;
+  
+       /*  printf("QS: %d - %d\n", node, c_exceptionVisit[node]);                                      */
+   
+
+       if (c_exceptionVisit[node] > 0) {       /* node is part of exception graph              */
+               c_exceptionVisit[node] = -1;
+               
+               bp = block[node];                               /* setup scan of all instructions               */
+               ip = bp.iinstr;
+               count = bp.icount;                              
+
+               for (i=0; i<count; ++i, ++ip) { /* for each instruction do                              */
+                       switch (ip->opc) {
+                       case ICMD_ISTORE:
+                       case ICMD_IINC:                         /* a variable is modified                               */
+       
+                               lv = c_loopvars;                /* is it an array index var ?                   */
+                               while (lv != NULL) {
+                                       if ((lv->index) && (lv->value == ip->op1))
+                                               return 1;               /* yes, so return 1                                             */
+                                       lv = lv->next;
+                                       }
+                               break;
+                               }
+                       }
+  
+           d = c_exceptionGraph[node];         /* check all successor nodes                    */
+               while (d != NULL) {
+                       if (quick_scan(d->value) > 0)
+                               return 1;                               /* if an access is found return 1               */
+                       d = d->next;
+                       }
+
+               return 0;                                               /* nothing found, so return 0                   */
+               }
+       else
+               return 0;
+}
+
+/*     This function returns 1, when the condition of the loop contains 
+       or statements or when an array index variable is modified in any
+       catch block within the loop.
+*/
+int analyze_or_exceptions(int head, struct LoopContainer *lc)
+{
+       struct depthElement *d, *tmp, *tmp2;
+       int i, j, k, value, flag, count;
+       struct LoopElement *le;
+
+       d = c_dTable[head];
+       count = flag = 0;
+
+       /* analyze for or-statements                                                                                            */
+#ifdef LOOP_DEBUG
+       printf("*** Analyze for OR ... ");                                                                              
+       fflush(stdout);
+#endif
+
+       while (d != NULL) {                             /* for all successor nodes check if they        */
+               value = d->value;                       /* are part of the loop                                         */
+
+               le = lc->nodes;
+
+               while (le != NULL) {
+                       if (le->node == value)
+                               break;
+                       le = le->next;
+                       }
+
+               if (le == NULL)                         /* node is not part of the loop                         */
+                       ++flag;                                 
+
+               d = d->next;
+               ++count;
+               }
+
+       if ((count > 1) && (flag == 0)){/* if all successors part of the loop, exit */
+#ifdef STATISTICS
+               c_stat_or++;
+#endif
+               return 0;
+               }
+
+       /* check for exceptions */
+       /* printf("done\n*** Analyze for EXCEPTIONS(%d) . ", exceptiontablelength);     */
+
+       if (!exceptiontablelength)              /* when there are no exceptions, exit           */
+               return 1;
+
+       if ((c_exceptionGraph = (struct depthElement **) malloc(sizeof(struct depthElement *) * block_count)) == NULL)
+               c_mem_error();
+       if ((c_exceptionVisit = (int *) malloc(sizeof(int) * block_count)) == NULL)
+               c_mem_error();
+       
+       for (k=0; k<block_count; ++k) {
+               c_exceptionVisit[k] = -1;
+               c_exceptionGraph[k] = NULL;
+               }
+
+
+       /* for all nodes that start catch block check whether they are part of loop     */
+       for (i = 0; i < c_old_xtablelength; i++) {      
+               value = block_index[extable[i].startpc];
+   
+               le = lc->nodes;
+               while (le != NULL) {
+
+                       if (le->node == value)  {                       /* exception is in loop                 */
+#ifdef LOOP_DEBUG
+                               printf("C_INFO: Loop contains exception\n");                                    
+                               fflush(stdout);
+#endif
+
+                               /* build a graph structure, that contains all nodes that are    */
+                               /* part of the catc block                                                                               */
+                               dF_Exception(-1, block_index[extable[i].handlerpc]);
+
+                               /* if array index variables are modified there, return 0                */
+                               if (quick_scan(block_index[extable[i].handlerpc]) > 0) {
+#ifdef STATISTICS
+                                       c_stat_exception++;
+#endif
+                                       /* printf("C_INFO: loopVar modified in exception\n");           */
+                                       return 0;
+                                       }
+                               }
+                       le = le->next;
+                       }
+               }
+
+#ifdef LOOP_DEBUG
+       printf("none ... done\n");                                                                                              
+       fflush(stdout);
+#endif
+       return 1;
+}
+
+/*     This function sets a flag in c_var_modified for all variables that have
+       been found as part of an assigment in the loop.
+*/
+void scan_global_list()
+{
+       struct LoopVar *lv;
+       lv = c_loopvars;
+
+       while (lv != NULL) {
+               if (lv->modified)
+                       c_var_modified[lv->value] = 1;
+               lv = lv->next;
+               }
+}
+
+/*     This function analyses the condition in the loop header and trys to find
+       out, whether some dynamic guarantees can be set up.
+*/
+void init_constraints(int head)
+{
+       basicblock bp;
+       instruction *ip;
+       int ic, l_mod, r_mod, changed, operand;
+       struct Trace *left, *right, *th;
+       struct LoopVar *lv_left, *lv_right, *lh;
+
+       bp = block[head];
+       ic = bp.icount;
+       ip = bp.iinstr+(ic-1);  /* set ip to last instruction in header node            */
+
+       switch (ip->opc) {              /* check op-code                                                                        */
+               
+       /* comparison against constant value                                                                            */
+       case ICMD_IFEQ:                 /* ..., value ==> ...                                                           */
+       case ICMD_IFLT:         /* ..., value ==> ...                                                           */
+       case ICMD_IFLE:         /* ..., value ==> ...                                                           */
+       case ICMD_IFGT:         /* ..., value ==> ...                                                           */
+       case ICMD_IFGE:         /* ..., value ==> ...                                                           */
+                                                       /* op1 = target JavaVM pc, val.i = constant                     */
+
+               left = tracing(&bp, ic-2, 0);   /* analyse left arg., right is constant */
+               right = create_trace(TRACE_ICONST, -1, ip->val.i, 0);
+               break;
+
+       /* standard comparison                                                                                                          */
+       case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                                            */
+       case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                                            */
+       case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                                            */
+       case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                                            */
+       case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                                            */
+               
+               left = tracing(&bp, ic-2, 1);   /* get left and right argument                  */
+               right = tracing(&bp, ic-2, 0);
+               break;
+       
+       /* other condition                                                                                                                      */
+       default:
+               left = create_trace(TRACE_UNKNOWN, -1, 0, 0);
+               right = create_trace(TRACE_UNKNOWN, -1, 0, 0);
+               break;
+               }
+
+       /* analyse left and right side of comparison                                                            */
+       l_mod = r_mod = 0;
+
+       if (left->type == TRACE_IVAR) { /* is a loop variable on left side ?            */
+               lv_left = c_loopvars;
+               while (lv_left != NULL) {
+                       if (lv_left->value == left->var) {
+                               l_mod = lv_left->modified;      /* yes, but has it been modified ?      */       
+                               break;                          
+                               }
+                       lv_left = lv_left->next;
+                       }
+               }
+
+       if (right->type == TRACE_IVAR){ /* is a loop variable on right side ?           */
+               lv_right = c_loopvars;
+               while (lv_right != NULL) {
+                       if (lv_right->value == right->var) {
+                               r_mod = lv_right->modified;     /* yes, but has it been modified ?      */
+                               break;
+                               }
+                       lv_right = lv_right->next;
+                       }
+               }
+
+       if ((l_mod - r_mod) == 0) {             /* both 1 or both 0 -> no dynamic contraints*/
+               c_rightside = NULL;                     /* possible                                                                     */
+               return;
+               }
+
+       /* to simplify processing, make the left side the one, that contains the        */
+       /* modified variable                                                                                                            */
+       if (r_mod > l_mod) {
+               th = left;    left = right;        right = th;
+               lh = lv_left; lv_left = lv_right;  lv_right = lh;
+               changed = 1;                            /* set changed to true                                          */
+               }
+       else
+               changed = 0;                            /* no change needed                                                     */ 
+
+       /* make sure that right side's value does not change during loop execution      */ 
+       if (right->type == TRACE_UNKNOWN) {
+               c_rightside = NULL;
+               return;
+               }
+
+       /* determine operands:                                                                                                          */
+       /* for further explaination a is modified, b nonmodified var                            */
+       switch (ip->opc) {              /* check opcode again                                                           */      
+       case ICMD_IFEQ:         /* ..., value ==> ...                                                           */
+       case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                                            */
+               operand = OP_EQ;                                /* a == b                                                               */
+               break;
+
+       case ICMD_IFLE:         /* ..., value ==> ...                                                           */
+       case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                                            */
+               if (changed)
+                       operand = OP_GE;                        /* b<=a         -> a>=b                                         */
+               else {
+                       operand = OP_LT;                        /* a<=b         -> a<(b+1)                                      */ 
+                       if (left->constant != 0)
+                               left->constant -= 1;
+                       else
+                               right->constant += 1;   
+                       }
+               break;
+
+       case ICMD_IFLT:         /* ..., value ==> ...                                                           */
+       case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                                            */
+               if (changed) {
+                       operand = OP_GE;                        /* b<a          -> a>=(b+1)                                     */
+                       if (left->constant != 0)
+                               left->constant -= 1;
+                       else
+                               right->constant += 1;   
+                       }
+               else
+                       operand = OP_LT;                        /* a<b          -> a<b                                          */
+               break;
+
+       case ICMD_IFGT:         /* ..., value ==> ...                                                           */
+       case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                                            */
+               if (changed)
+                       operand = OP_LT;                        /* b>a          -> a<b                                          */
+               else {
+                       operand = OP_GE;                        /* a>b          ->      a>=(b+1)                                */
+                       if (left->constant != 0)
+                               left->constant -= 1;
+                       else
+                               right->constant += 1;
+                       }
+               break;
+               
+       case ICMD_IFGE:         /* ..., value ==> ...                                                           */
+       case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                                            */
+               if (changed) {
+                       operand = OP_LT;                        /* b>=a         -> a<(b+1)                                      */
+                       if (left->constant != 0)
+                               left->constant -= 1;
+                       else
+                               right->constant += 1;
+                       }
+               else
+                       operand = OP_GE;                        /* a>=b         -> a>=b                                         */
+               break;
+
+       default:
+               printf("C_ERROR: debugging error 0x00\n");
+               }
+
+
+       /* NOW: left/lv_left -> loopVar                                                                                         */
+       /*              right/lv_right -> const, nonmod. var, arraylength                                       */
+       switch (operand) {                                      /* check operand                                                */
+       case OP_EQ:
+               lv_left->dynamic_u_v = 1;               /* upper + lower bound tested                   */
+               lv_left->dynamic_l_v = 1;
+       
+               lv_left->dynamic_l = lv_left->dynamic_u = left->constant;
+               break;
+
+       case OP_LT:
+               lv_left->dynamic_u_v = 1;               /* upper bound tested                                   */
+       
+               lv_left->dynamic_u = left->constant;
+               break;
+
+       case OP_GE:
+               lv_left->dynamic_l_v = 1;               /* lower bound tested                                   */
+       
+               lv_left->dynamic_l = left->constant;
+               break;
+
+       default:
+               printf("C_ERROR: debugging error 0x01\n");
+               }
+
+       c_rightside = right;
+
+       switch (c_rightside->type) {
+       case TRACE_ICONST:
+               c_rs_needed_instr = 1;
+               break;
+       case TRACE_ALENGTH:
+               c_rs_needed_instr = 2;
+               break;
+       case TRACE_IVAR:
+               c_rs_needed_instr = 3;
+               break;
+       default:
+               printf("C_ERROR: wrong right-side type\n");
+               }
+}
+
+/*     This function is needed to add and record new static tests (before loop
+       entry) of variables to make guaratees for index variables. type states
+       the kind of the test. arrayRef is the array, which length is tested
+       against, varRef is the variable, that is testes and constant is the
+       constant value, that is tested.
+*/
+void add_new_constraint(int type, int arrayRef, int varRef, int constant)
+{
+       struct Constraint *tc;
+
+       switch (type) {
+       case TEST_ZERO:                                 /* a variable is tested against a const         */
+
+               tc = c_constraints[varRef];     /* does a test already exist for this var ?     */
+               while (tc != NULL) {
+                       if (tc->type == TEST_ZERO) {
+                               if (constant < tc->constant)
+                                       tc->constant = constant;
+                               return;                         /* yes. update constant and return                      */
+                               }
+                               tc = tc->next;
+                       }
+
+               /* insert a new test for this variable                                                                  */
+               if ((tc = (struct Constraint *) malloc(sizeof(struct Constraint))) == NULL)
+                       c_mem_error();
+               tc->type     = TEST_ZERO;
+               tc->varRef   = varRef;
+               tc->constant = constant;
+               tc->next     = c_constraints[varRef];
+               c_constraints[varRef] = tc;
+               c_needed_instr += 3;
+
+               break;
+
+       case TEST_ALENGTH:                              /* variable is tested against array length      */
+
+               tc = c_constraints[varRef];     /* does a test already exist for this var ?     */
+               while (tc != NULL) {
+                       if ((tc->type == TEST_ALENGTH) && (tc->arrayRef == arrayRef)) {
+                               if (constant > tc->constant)
+                                       tc->constant = constant;
+                               return;                         /* yes. update constant and return                      */
+                               }
+                       tc = tc->next;
+                       }
+
+               /* insert a new test for this variable                                                                  */
+               if ((tc = (struct Constraint *) malloc(sizeof(struct Constraint))) == NULL)
+                       c_mem_error();
+               tc->type         = TEST_ALENGTH;
+               tc->arrayRef = arrayRef;
+               tc->varRef   = varRef;
+               tc->constant = constant;
+               tc->next     = c_constraints[varRef];
+               c_constraints[varRef] = tc;
+               c_needed_instr += 6;
+
+               /* if arrayRef is not already tested against null, insert that test     */
+               if (!(c_null_check[arrayRef])) {
+                       c_null_check[arrayRef] = 1;
+                       c_needed_instr +=2;
+                   }
+                       
+               break;
+
+       case TEST_CONST_ZERO:           
+               /* done earlier                                                                                                                 */
+               break;
+
+       case TEST_CONST_ALENGTH:                /* a const is tested against array length       */
+
+               /* does a test already exist for this array                                                             */
+               tc = c_constraints[maxlocals];
+               while (tc != NULL) {
+                       if ((tc->type == TEST_CONST_ALENGTH) && (tc->arrayRef == arrayRef)) {
+                               if (constant > tc->constant)
+                                       tc->constant = constant;
+                               return;                         /* yes. update constant and return                      */
+                               }
+                       tc = tc->next;
+                       }
+               
+               /* insert a new test for this array                                                                             */
+               if ((tc = (struct Constraint *) malloc(sizeof(struct Constraint))) == NULL)
+                       c_mem_error();
+               tc->type         = TEST_CONST_ALENGTH;
+               tc->arrayRef = arrayRef;
+               tc->constant = constant;
+               tc->next     = c_constraints[maxlocals];
+               c_constraints[maxlocals] = tc;
+               c_needed_instr += 4;
+
+               /* if arrayRef is not already tested against null, insert that test     */
+               if (!(c_null_check[arrayRef])) {
+                       c_null_check[arrayRef] = 1;
+                       c_needed_instr +=2;
+                   }
+
+               break;
+
+       case TEST_UNMOD_ZERO:                   /* test unmodified var against constant         */
+
+               /* search if test already exists                                                                                */
+               tc = c_constraints[varRef];
+               while (tc != NULL) {
+                       if (tc->type == TEST_UNMOD_ZERO) {
+                               if (constant < tc->constant)
+                                       tc->constant = constant;
+                               return;                         /* yes, so update constant                                      */
+                               }
+                       tc = tc->next;
+                       }
+               
+               /* else, a new test is inserted                                                                                 */              
+               if ((tc = (struct Constraint *) malloc(sizeof(struct Constraint))) == NULL)
+                       c_mem_error();
+               tc->type         = TEST_UNMOD_ZERO;
+               tc->varRef   = varRef;
+               tc->constant = constant;
+               tc->next     = c_constraints[varRef];
+               c_constraints[varRef] = tc;
+               c_needed_instr += 3;
+
+               break;
+       
+       case TEST_UNMOD_ALENGTH:                /* test unmodified var against array length     */
+
+               /* search if test alreay exists                                                                                 */
+               tc = c_constraints[varRef];
+               while (tc != NULL) {
+                       if ((tc->type == TEST_UNMOD_ALENGTH) && (tc->arrayRef == arrayRef)) {
+                               if (constant > tc->constant)
+                                       tc->constant = constant;        
+                               return;                         /* yes, so modify constants                                     */
+                               }
+                       tc = tc->next;
+                       }
+               
+               /* create new entry                                                                                                             */
+               if ((tc = (struct Constraint *) malloc(sizeof(struct Constraint))) == NULL)
+                       c_mem_error();
+               tc->type         = TEST_UNMOD_ALENGTH;
+               tc->varRef   = varRef;
+               tc->arrayRef = arrayRef;
+               tc->constant = constant;
+               tc->next     = c_constraints[varRef];
+               c_constraints[varRef] = tc;
+               c_needed_instr += 6;
+
+               /* if arrayRef is not already tested against null, insert that test     */
+               if (!(c_null_check[arrayRef])) {
+                       c_null_check[arrayRef] = 1;
+                       c_needed_instr +=2;
+                   }
+
+               break;
+       
+       case TEST_RS_ZERO:                              /* test right side of the loop condition        */
+                                                                       /* against a constant - needed by dynamic       */
+                                                                       /* checks                                                                       */
+               /*!! varRef -> maxlocals */
+               /* search if test already exists                                                                                */
+               tc = c_constraints[maxlocals];
+               while (tc != NULL) {
+                       if (tc->type == TEST_RS_ZERO) {
+                               if (constant < tc->constant)
+                                       tc->constant = constant;
+                               return;                         /* yes, so modify constants                                     */
+                               }
+                       tc = tc->next;
+                       }
+
+               /* create new entry                                                                                                             */
+               if ((tc = (struct Constraint *) malloc(sizeof(struct Constraint))) == NULL)
+                       c_mem_error();
+               tc->type     = TEST_RS_ZERO;
+               tc->constant = constant;
+               tc->next     = c_constraints[maxlocals];
+               c_constraints[maxlocals] = tc;
+               c_needed_instr += (2 + c_rs_needed_instr);
+
+               /* if arrayRef on right side is not already tested against null,        */
+               /* insert that test                                                     */
+               if ((c_rightside->type == TRACE_ALENGTH) && (!(c_null_check[c_rightside->var]))) {
+                       c_null_check[c_rightside->var] = 1;
+                       c_needed_instr +=2;
+                   }
+
+               break;
+               
+       case TEST_RS_ALENGTH:                   /* test right side of the loop condition        */
+                                                                       /* against array length - needed by dynamic     */
+                                                                       /* checks                                                                       */
+               /*!! varRef -> maxlocals */
+               /* search if test already exists                                                                                */
+               tc = c_constraints[maxlocals];
+               while (tc != NULL)
+               {
+                       if ((tc->type == TEST_RS_ALENGTH) && (tc->arrayRef == arrayRef))
+                       {
+                               if (constant > tc->constant)
+                                       tc->constant = constant;
+                               return;                         /* yes, so modify constants                                     */
+                       }
+                       tc = tc->next;
+               }
+
+               /* create new entry                                                                                                             */
+               if ((tc = (struct Constraint *) malloc(sizeof(struct Constraint))) == NULL)
+                       c_mem_error();
+               tc->type         = TEST_RS_ALENGTH;
+               tc->arrayRef = arrayRef;
+               tc->constant = constant;
+               tc->next     = c_constraints[maxlocals];
+               c_constraints[maxlocals] = tc;
+               c_needed_instr += (3 + c_rs_needed_instr);
+
+               /* if arrayRef is not already tested against null, insert that test     */
+               if (!(c_null_check[arrayRef])) {
+                       c_null_check[arrayRef] = 1;
+                       c_needed_instr +=2;
+                   }
+
+               /* if arrayRef on right side is not already tested against null,        */
+               /* insert that test                                                     */
+               if ((c_rightside->type == TRACE_ALENGTH) && (!(c_null_check[c_rightside->var]))) {
+                       c_null_check[c_rightside->var] = 1;
+                       c_needed_instr +=2;
+                   }
+               break;
+
+       }
+}
+
+/*     This functions adds new static (before loop enry) tests of variables to the
+       program to be able to guarantee certain values for index variables in array
+       access (to safely remove bound checks).
+*/
+int insert_static(int arrayRef, struct Trace *index, struct Changes *varChanges, int special)
+{
+       struct Constraint *tc;
+       struct LoopVar *lv;
+       int varRef;
+       int high, low;
+       
+       /* printf("insert static check - %d\n", arrayRef);
+          show_trace(index);
+          show_change(varChanges);
+       */
+
+       if (varChanges == NULL) {                       /* the variable hasn't changed / const  */
+               if ((varChanges = (struct Changes *) malloc(sizeof(struct Changes))) == NULL)
+                       c_mem_error();
+               varChanges->lower_bound = varChanges->upper_bound = 0;
+               }
+
+       switch (index->type) {                          /* check index type                                             */
+       case TRACE_IVAR:                                        /* it is a variable                                             */
+               if (index->neg < 0) {                   /* if it's a negated var, return                */
+#ifdef STATISTICS
+                       c_stat_no_opt++;                        
+#endif
+                       return OPT_NONE;
+                       }
+
+               varRef = index->var;
+               high = low = 0;
+
+               if (c_var_modified[varRef])     {       /* volatile var                                                 */
+                       
+                       lv = c_loopvars;                        /* get reference to loop variable               */
+
+                       while ((lv != NULL) && (lv->value != varRef))
+                               lv = lv->next;
+                       if (lv == NULL)
+                         printf("C_ERROR: debugging error 0x02\n");
+
+                       /* show_varinfo(lv);                                                                                            */
+                       
+                       /* check existing static bounds and add new contraints on variable      */
+                       /* to possibly remove bound checks                                                                      */
+                       if (lv->static_l) {
+                               /* the var is never decremented, so we add a static test againt */
+                               /* constant                                                                                                             */
+                               if (varChanges->lower_bound > varChanges->upper_bound)
+                                       add_new_constraint(TEST_ZERO, arrayRef, varRef, index->constant);
+                               else
+                                       add_new_constraint(TEST_ZERO, arrayRef, varRef, varChanges->lower_bound+index->constant);
+                               low = 1;
+                               }
+                       else if ((lv->dynamic_l_v) && (!special)) {
+                               /* the variable is decremented, but it is checked against a             */
+                               /* bound in the loop condition                                                                  */
+                               if (varChanges->lower_bound <= varChanges->upper_bound) {
+                                       add_new_constraint(TEST_RS_ZERO, arrayRef, varRef, varChanges->lower_bound+index->constant+lv->dynamic_l);
+                                       low = 1;
+                                       }
+                               }
+
+                       if (lv->static_u) {
+                               /* the var is never incremented, so we add a static test againt */
+                               /* constant                                                                                                             */
+                               if (varChanges->lower_bound > varChanges->upper_bound)
+                                       add_new_constraint(TEST_ALENGTH, arrayRef, varRef, index->constant);
+                               else
+                                       add_new_constraint(TEST_ALENGTH, arrayRef, varRef, varChanges->upper_bound+index->constant);
+                               high = 1;
+                               }
+                       else if ((lv->dynamic_u_v) &&  (!special)) {
+                               /* the variable is decremented, but it is checked against a             */
+                               /* bound in the loop condition                                                                  */
+                               if (varChanges->lower_bound <= varChanges->upper_bound) {
+                                       add_new_constraint(TEST_RS_ALENGTH, arrayRef, varRef, varChanges->upper_bound+index->constant+lv->dynamic_u);
+                                       high = 1;
+                                       }
+                               }
+                       }
+               else {                                                  /* the var is never modified at all             */
+                       add_new_constraint(TEST_UNMOD_ZERO, arrayRef, index->var, index->constant);
+                       add_new_constraint(TEST_UNMOD_ALENGTH, arrayRef, index->var, index->constant);
+                       low = high = 1;
+                       }
+               
+               /* if the addition of new variable tests made guarantees possible,              */
+               /* return the best possible optimization                                                                */
+               if ((high > 0) && (low > 0)) {
+                       /* printf("fully optimzed\n");                                                                          */
+#ifdef STATISTICS
+                       c_stat_full_opt++;                      
+#endif
+                       return OPT_FULL;
+                       }
+               else if (high > 0) {
+                       /* printf("upper optimzed\n");                                                                          */
+#ifdef STATISTICS
+                       c_stat_upper_opt++;                     
+#endif
+                       return OPT_UPPER;
+                       }
+               else if (low > 0) {
+                       /* printf("lower optimzed\n");                                                                          */
+#ifdef STATISTICS
+                       c_stat_lower_opt++;                     
+#endif
+                       return OPT_LOWER;
+                       }
+               else {
+                       /* printf("not optimzed\n");                                                                            */
+#ifdef STATISTICS
+                       c_stat_no_opt++;                        
+#endif
+                       return OPT_NONE;
+                       }
+               break;
+
+       case TRACE_ICONST:                      /* if it is a constant, optimization is easy    */
+               if (index->constant < 0) {
+#ifdef STATISTICS
+                       c_stat_no_opt++;                        
+#endif
+                       return OPT_NONE;        /* negative index -> bad                                                */
+                       }
+               else {
+                       add_new_constraint(TEST_CONST_ALENGTH, arrayRef, 0, index->constant);
+#ifdef STATISTICS
+                       c_stat_full_opt++;                      
+#endif
+                       return OPT_FULL;        /* else just test constant against array length */
+                       }
+               break;
+
+       case TRACE_ALENGTH:                     /* else, no optimizations possible                              */
+       case TRACE_UNKNOWN: 
+       case TRACE_AVAR:    
+#ifdef STATISTICS
+               c_stat_no_opt++;                        
+#endif
+               return OPT_NONE;
+               }
+}
+
+
+
+/*     copy a stack and return the start pointer of the newly created one
+*/
+stackptr copy_stack_from(stackptr source) { 
+       stackptr current, top;
+
+       if (source == NULL)
+               return NULL;
+
+       /* copy first element                                                       */
+       current = DMNEW(stackelement, 1);
+       current->type = source->type;
+       current->flags = source->flags;
+       current->varkind = source->varkind;
+       current->varnum = source->varnum;
+       current->regoff = source->regoff;
+       
+       top = current;
+
+       /* if there exist more, then copy the rest                                  */
+       while (source->prev != NULL) {
+               source = source->prev;
+               current->prev = DMNEW(stackelement, 1);
+               current->type = source->type;
+               current->flags = source->flags;
+               current->varkind = source->varkind;
+               current->varnum = source->varnum;
+               current->regoff = source->regoff;
+               current = current->prev;
+               }
+
+       current->prev = NULL;
+       return top;
+}
+
+
+/* The following defines are used in the procedure void create_static_checks(...)
+   They add a new instruction with its corresponding stack manipulation and
+   are used to build the new loop header of an optimized loop, where we have
+   to check certain variables and constants against values to guarantee that 
+   index values in array accesses remain with array bounds.
+
+   inst: pointer to the new instruction
+   tos: stackpointer before this operation is executed
+   newstack: temporary stackptr
+   stackdepth: counts the current stackdepth
+   original start: blockpointer to the head of the new, optimized loop 
+*/
+
+/* Load a local integer variable v                                              */
+#define LOAD_VAR(v) { \
+       inst->opc = ICMD_ILOAD; \
+       inst->op1 = v; \
+       newstack = DMNEW(stackelement, 1); \
+    inst->dst = newstack; \
+       newstack->prev = tos; \
+       newstack->type = TYPE_INT; \
+       newstack->flags = 0; \
+       newstack->varkind = LOCALVAR; \
+       newstack->varnum = v; \
+       tos = newstack; \
+       inst++; \
+       stackdepth++; \
+       }
+
+/* Load a constant with value c                                                 */
+#define LOAD_CONST(c) { \
+       inst->opc = ICMD_ICONST; \
+       inst->op1 = 0; \
+       inst->val.i = (c); \
+       newstack = DMNEW(stackelement, 1); \
+       newstack->prev = tos; \
+       newstack->type = TYPE_INT; \
+       newstack->flags = 0; \
+       newstack->varkind = UNDEFVAR; \
+       newstack->varnum = stackdepth; \
+       tos = newstack; \
+       inst->dst = tos; \
+       inst++; \
+       stackdepth++; \
+       }
+
+/* Load a local reference (adress) variable a                                   */
+#define LOAD_ADDR(a) { \
+       inst->opc = ICMD_ALOAD; \
+       inst->op1 = a; \
+       newstack = DMNEW(stackelement, 1); \
+       newstack->prev = tos; \
+       newstack->type = TYPE_ADR; \
+       newstack->flags = 0; \
+       newstack->varkind = LOCALVAR; \
+       newstack->varnum = a; \
+       tos = newstack; \
+       inst->dst = tos; \
+       inst++; \
+       stackdepth++; \
+       }
+
+/* Insert a compare greater-or-equal and jump to the unoptimized loop, if the   */
+/* comparison is true                                                           */
+#define GOTO_NOOPT_IF_GE { \
+       inst->opc = ICMD_IF_ICMPGE; \
+    inst->target = original_start->copied_to; \
+       if (tos->varkind == UNDEFVAR) \
+               tos->varkind = TEMPVAR;  \
+    tos = tos->prev; \
+    if (tos->varkind == UNDEFVAR) \
+               tos->varkind = TEMPVAR;  \
+    tos = tos->prev; \
+       inst->dst = tos; \
+       inst++; \
+       stackdepth -= 2; \
+       }
+
+/* Insert a compare greater than and jump to the unoptimized loop, if the       */
+/* comparison is true                                                           */
+#define GOTO_NOOPT_IF_GT { \
+       inst->opc = ICMD_IF_ICMPGT; \
+    inst->target = original_start->copied_to; \
+       if (tos->varkind == UNDEFVAR) \
+               tos->varkind = TEMPVAR;  \
+    tos = tos->prev; \
+    if (tos->varkind == UNDEFVAR) \
+               tos->varkind = TEMPVAR;  \
+    tos = tos->prev; \
+       inst->dst = tos; \
+       inst++; \
+       stackdepth -= 2; \
+       }
+
+
+/* Insert a compare less-than and jump to the unoptimized loop, if the          */
+/* comparison is true                                                           */
+#define GOTO_NOOPT_IF_LT { \
+       inst->opc = ICMD_IF_ICMPLT; \
+    inst->target = original_start->copied_to; \
+       if(tos->varkind == UNDEFVAR) \
+               tos->varkind = TEMPVAR;  \
+    tos = tos->prev; \
+    if(tos->varkind == UNDEFVAR) \
+               tos->varkind = TEMPVAR;  \
+    tos = tos->prev; \
+       inst->dst = tos; \
+       inst++; \
+       stackdepth -= 2; \
+       }
+
+/* Insert a compare if-not-null and jump to the unoptimized loop, if the        */
+/* comparison is true                                                           */
+#define GOTO_NOOPT_IF_NULL { \
+       inst->opc = ICMD_IFNULL; \
+    inst->target = original_start->copied_to; \
+    if(tos->varkind == UNDEFVAR) \
+               tos->varkind = TEMPVAR;  \
+    tos = tos->prev; \
+       inst->dst = tos; \
+       inst++; \
+       stackdepth -= 1; \
+       }
+
+/* Insert an add instruction, that adds two integer values on top of the stack  */
+/* together                                                                     */
+#define ADD { \
+       inst->opc = ICMD_IADD; \
+       if(tos->varkind == UNDEFVAR) \
+               tos->varkind = TEMPVAR;  \
+    tos = tos->prev; \
+    if(tos->varkind == UNDEFVAR) \
+               tos->varkind = TEMPVAR;  \
+    tos = tos->prev; \
+       newstack = DMNEW(stackelement, 1); \
+       newstack->prev = tos; \
+       newstack->type = TYPE_INT; \
+       newstack->flags = 0; \
+       newstack->varkind = UNDEFVAR; \
+       newstack->varnum = stackdepth; \
+       tos = newstack; \
+       inst->dst = tos; \
+       inst++; \
+       stackdepth--; \
+       }
+               
+/* Insert instructions to load the arraylength of an array with reference a     */
+/* fisrt, the reference must be loaded, then a null-pointer check is inserted   */
+/* if not already done earlier. Finally an arraylength instruction is added     */
+#define LOAD_ARRAYLENGTH(a) { \
+    if (c_null_check[a]) { \
+               LOAD_ADDR(a); \
+               GOTO_NOOPT_IF_NULL; \
+               c_null_check[a] = 0; \
+           }  \
+       LOAD_ADDR(a); \
+    inst->opc = ICMD_ARRAYLENGTH; \
+       if(tos->varkind == UNDEFVAR) \
+               tos->varkind = TEMPVAR;  \
+    tos = tos->prev; \
+       newstack = DMNEW(stackelement, 1); \
+       newstack->prev = tos; \
+       newstack->type = TYPE_INT; \
+       newstack->flags = 0; \
+       newstack->varkind = UNDEFVAR; \
+       newstack->varnum = stackdepth; \
+       tos = newstack; \
+       inst->dst = tos; \
+       inst++; \
+       }       
+
+
+/* Inserts the instructions to load the value of the right side of comparison   */
+/* Depending of the type of the right side, the apropriate instructions are     */
+/* created.                                                                     */
+#define LOAD_RIGHT_SIDE { \
+       switch (c_rightside->type) { \
+       case TRACE_ICONST: \
+               LOAD_CONST(c_rightside->constant); \
+               break; \
+       case TRACE_IVAR: \
+               LOAD_VAR(c_rightside->var); \
+               LOAD_CONST(c_rightside->constant); \
+               ADD; \
+               break; \
+       case TRACE_ALENGTH: \
+               LOAD_ARRAYLENGTH(c_rightside->var); \
+               break; \
+       default: \
+               printf("C_ERROR: illegal trace on rightside of loop-header\n"); \
+               exit; \
+               } \
+}
+
+/*     Patch jumps in original loop and in copied loop, add gotos in copied loop.
+       All jumps in the original loop to the loop head have to be redirected to
+       the newly inserted one. For the copied loop, it is necessay to redirect all
+       jumps inside that loop to the copied nodes. lc points to the current loop, 
+       loop_head is a pointer to the newly inserted head and original start was
+       the old head and is now the head of the optimized variant of the loop.
+*/
+void patch_jumps(basicblock *original_start, basicblock *loop_head, struct LoopContainer *lc)
+{
+       /* step through all nodes of a loop                                         */
+       struct LoopElement *le;
+       basicblock *bptr;
+       instruction *inst, *temp_instr;
+       int i;
+
+       le = lc->nodes;
+       while (le != NULL) {
+
+               /* do nothing for new loop head                                         */
+               if (le->block == loop_head) {
+                       le = le->next;
+                       continue;
+                   }
+
+               /* for original version                                                 */
+               bptr = le->block;
+               inst = bptr->iinstr;
+               for (i = 0; i < bptr->icount; ++i, ++inst) {
+                       switch (inst->opc) {
+
+                       case ICMD_IF_ICMPEQ:
+                       case ICMD_IF_ICMPLT:
+                       case ICMD_IF_ICMPLE:
+                       case ICMD_IF_ICMPNE:
+                       case ICMD_IF_ICMPGT:
+                       case ICMD_IF_ICMPGE:
+
+                       case ICMD_IF_LCMPEQ:
+                       case ICMD_IF_LCMPLT:
+                       case ICMD_IF_LCMPLE:
+                       case ICMD_IF_LCMPNE:
+                       case ICMD_IF_LCMPGT:
+                       case ICMD_IF_LCMPGE:
+
+                       case ICMD_IF_ACMPEQ:
+                       case ICMD_IF_ACMPNE:
+
+                       case ICMD_IFEQ:
+                       case ICMD_IFNE:
+                       case ICMD_IFLT:
+                       case ICMD_IFGE:
+                       case ICMD_IFGT:
+                       case ICMD_IFLE:
+
+                       case ICMD_IF_LEQ:
+                       case ICMD_IF_LNE:
+                       case ICMD_IF_LLT:
+                       case ICMD_IF_LGE:
+                       case ICMD_IF_LGT:
+                       case ICMD_IF_LLE:
+
+                       case ICMD_GOTO:
+                       case ICMD_JSR:
+                       case ICMD_IFNULL:
+                       case ICMD_IFNONNULL:
+
+                               /* jump to newly inserted loopheader has to be redirected       */
+                               if (((basicblock *) inst->target) == loop_head)
+                                       inst->target = (void *) original_start;
+                               break;
+
+                       case ICMD_TABLESWITCH:
+                               {
+                                       s4 *s4ptr, l, i;
+                                       void **tptr;
+
+                                       tptr = (void **) inst->target;
+
+                                       s4ptr = inst->val.a;
+                                       l = s4ptr[1];                          /* low     */
+                                       i = s4ptr[2];                          /* high    */
+
+                                       i = i - l + 1;
+
+                                       /* jump to newly inserted loopheader has to be redirected   */
+                                       for (tptr = inst->target; i >= 0; --i, ++tptr) {
+                                               if (((basicblock *) *tptr) == loop_head)
+                                                       tptr[0] = (void *) original_start;
+                                               }
+                               }
+                               break;
+
+                       case ICMD_LOOKUPSWITCH:
+                               {
+                                       s4 i, l, val, *s4ptr;
+                                       void **tptr;
+
+                                       tptr = (void **) inst->target;
+
+                                       s4ptr = inst->val.a;
+                                       l = s4ptr[0];                          /* default  */
+                                       i = s4ptr[1];                          /* count    */
+
+                                       /* jump to newly inserted loopheader has to be redirected   */
+                                       for (tptr = inst->target; i >= 0; --i, ++tptr) {
+                                               if (((basicblock *) *tptr) == loop_head)
+                                                       tptr[0] = (void *) original_start;
+                                               }
+                               }
+                               break;
+
+                               }
+                       }
+
+               /* if node is part of loop and has fall through to original start, that */
+               /* must be redirected. Unfortunately the instructions have to be copied */
+
+               if (bptr->next == loop_head) {
+                       temp_instr = DMNEW(instruction, bptr->icount + 1);
+                       memcpy(temp_instr, bptr->iinstr, sizeof(instruction)*bptr->icount);
+                       bptr->iinstr = temp_instr;
+
+                       bptr->iinstr[bptr->icount].opc = ICMD_GOTO;
+                       bptr->iinstr[bptr->icount].target = original_start;
+                       bptr->iinstr[bptr->icount].dst = NULL;
+                       ++bptr->icount;
+                       }       
+               
+               /* for copied version - which gets the unoptimized variant              */
+               bptr = le->block->copied_to;
+               inst = bptr->iinstr;
+               for (i = 0; i < bptr->icount; ++i, ++inst) {
+
+                       switch (inst->opc) {
+
+                       case ICMD_IASTORE:                      /* array store                                                  */
+                       case ICMD_LASTORE:          
+                       case ICMD_FASTORE:          
+                       case ICMD_DASTORE:          
+                       case ICMD_AASTORE:          
+                       case ICMD_BASTORE:          
+                       case ICMD_CASTORE:          
+                       case ICMD_SASTORE:
+                       case ICMD_IALOAD:                       /* array load                                               */
+                   case ICMD_LALOAD:       
+                       case ICMD_FALOAD:
+                       case ICMD_DALOAD:
+                       case ICMD_AALOAD:
+                       case ICMD_BALOAD:
+                       case ICMD_CALOAD:
+                       case ICMD_SALOAD:
+
+                               /* undo previous optimizations in new loop                      */
+                               inst->op1 = 0;
+                               break;
+
+                       case ICMD_IF_ICMPEQ:
+                       case ICMD_IF_ICMPLT:
+                       case ICMD_IF_ICMPLE:
+                       case ICMD_IF_ICMPNE:
+                       case ICMD_IF_ICMPGT:
+                       case ICMD_IF_ICMPGE:
+
+                       case ICMD_IF_LCMPEQ:
+                       case ICMD_IF_LCMPLT:
+                       case ICMD_IF_LCMPLE:
+                       case ICMD_IF_LCMPNE:
+                       case ICMD_IF_LCMPGT:
+                       case ICMD_IF_LCMPGE:
+
+                       case ICMD_IF_ACMPEQ:
+                       case ICMD_IF_ACMPNE:
+
+                       case ICMD_IFEQ:
+                       case ICMD_IFNE:
+                       case ICMD_IFLT:
+                       case ICMD_IFGE:
+                       case ICMD_IFGT:
+                       case ICMD_IFLE:
+
+                       case ICMD_IF_LEQ:
+                       case ICMD_IF_LNE:
+                       case ICMD_IF_LLT:
+                       case ICMD_IF_LGE:
+                       case ICMD_IF_LGT:
+                       case ICMD_IF_LLE:
+
+                       case ICMD_GOTO:
+                       case ICMD_JSR:
+                       case ICMD_IFNULL:
+                       case ICMD_IFNONNULL:
+
+                               /* jump to newly inserted loopheader has to be redirected       */
+                               if (((basicblock *) inst->target) == loop_head)
+                                       inst->target = (void *) original_start->copied_to;
+                               /* jump to loop internal nodes has to be redirected             */
+                               else if (((basicblock *) inst->target)->lflags & LOOP_PART)
+                                       inst->target = (void *) ((basicblock *) inst->target)->copied_to;
+                               break;
+                               
+                       case ICMD_TABLESWITCH:
+                               {
+                                       s4 *s4ptr, l, i;
+                                       
+                                       void **copy_ptr, *base_ptr;
+                                       void **tptr;
+
+                                       tptr = (void **) inst->target;
+
+                                       s4ptr = inst->val.a;
+                                       l = s4ptr[1];                          /* low     */
+                                       i = s4ptr[2];                          /* high    */
+
+                                       i = i - l + 1;
+                                       
+                                       copy_ptr = (void**) DMNEW(void*, i+1);
+                                       base_ptr = (void*) copy_ptr;
+
+                                       /* Targets for switch instructions are stored in an extra   */
+                                       /* that must be copied for new inserted loop.               */
+
+                                       for (tptr = inst->target; i >= 0; --i, ++tptr, ++copy_ptr) {
+                                               /* jump to newly inserted loopheader must be redirected */
+                                               if (((basicblock *) *tptr) == loop_head)
+                                                       copy_ptr[0] = (void *) original_start->copied_to;
+                                               /* jump to loop internal nodes has to be redirected     */
+                                               else if (((basicblock *) *tptr)->lflags & LOOP_PART)
+                                                       copy_ptr[0] = (void *) ((basicblock *) tptr[0])->copied_to;
+                                               else
+                                                       copy_ptr[0] = tptr[0];
+                                               }
+
+                                       inst->target = base_ptr;
+                               }
+                               break;
+
+                       case ICMD_LOOKUPSWITCH:
+                               {
+                                       s4 i, l, val, *s4ptr;
+
+                                       void **copy_ptr, **base_ptr;
+                                       void **tptr;
+
+                                       tptr = (void **) inst->target;
+
+                                       s4ptr = inst->val.a;
+                                       l = s4ptr[0];                          /* default  */
+                                       i = s4ptr[1];                          /* count    */
+
+                                       copy_ptr = (void**) DMNEW(void*, i+1);
+                                       base_ptr = (void*) copy_ptr;
+
+                                       /* Targets for switch instructions are stored in an extra   */
+                                       /* that must be copied for new inserted loop.               */
+
+                                       for (tptr = inst->target; i >= 0; --i, ++tptr, ++copy_ptr) {
+                                               /* jump to newly inserted loopheader must be redirected */
+                                               if (((basicblock *) *tptr) == loop_head)
+                                                       copy_ptr[0] = (void *) original_start->copied_to;
+                                               /* jump to loop internal nodes has to be redirected     */
+                                               else if (((basicblock *) *tptr)->lflags & LOOP_PART)
+                                                       copy_ptr[0] = (void *) ((basicblock *) tptr[0])->copied_to;
+                                               else 
+                                                       copy_ptr[0] = tptr[0];
+                                               }
+
+                                       inst->target = base_ptr;
+                               }
+                               break;
+                               
+                               }
+                       }
+
+               /* if fall through exits loop, goto is needed                           */
+               if (!(le->block->next->lflags & LOOP_PART)) {
+                       bptr->iinstr[bptr->icount].opc = ICMD_GOTO;
+                       bptr->iinstr[bptr->icount].dst = NULL;
+                       bptr->iinstr[bptr->icount].target = le->block->next;
+                       bptr->icount++;
+                       }
+               
+               le = le->next;
+               }
+}
+
+/*     Add the new header node of a loop that has been duplicated to all parent 
+    loops in nesting hierarchie.
+*/
+void header_into_parent_loops(struct LoopContainer *lc, basicblock *to_insert, basicblock *replace, basicblock *after)
+{
+       /* we have to insert the node to_insert before the node after and replace   */
+       /* the pointer of to_insert by the node replace                             */
+
+       struct LoopElement *le, *t;
+
+       /* if the top of the tree is reached, then return                           */
+       if ((lc == NULL) || (lc == root))
+               return;
+
+       /* create new node, that should be inserted                                 */
+       t = DMNEW(struct LoopElement, 1);
+       t->block = to_insert;
+       t->node = -1;
+
+       /* first, find the node, that has to be replaced (= "to_insert") and        */
+       /* replace it by the node "replace"                                         */
+       le = lc->nodes;
+       while (le->block != to_insert)
+               le = le->next;
+       le->block = replace;
+
+       /* now find the node after and insert the newly create node before "after"  */
+       le = lc->nodes;
+       if (le->block == after) {
+               t->next = lc->nodes;
+               lc->nodes = t;
+           }
+       else {
+               while (le->next->block != after)
+                       le = le->next;
+
+               t->next = le->next;
+               le->next = t;
+           }
+
+       /* go up one hierarchie level                                               */
+       header_into_parent_loops(lc->parent, to_insert, replace, after);
+}
+
+/*     Add a new node (not header) of a duplicated loop to all parent loops in 
+    nesting hierarchie
+*/
+void node_into_parent_loops(struct LoopContainer *lc, basicblock *to_insert)
+{
+       struct LoopElement *le, *t;
+
+       /* if the top of the tree is reached, then return                           */
+       if ((lc == NULL) || (lc == root))
+               return;
+
+       /* create new node, that should be inserted                                 */
+       t = DMNEW(struct LoopElement, 1);
+       t->block = to_insert;
+       t->node = -1;
+
+       le = lc->nodes;
+
+       /* append new node to node list of loop                                     */
+       while (le->next != NULL)
+               le = le->next;
+
+       t->next = le->next;
+       le->next = t;
+
+       /* go up one hierarchie level                                               */
+       node_into_parent_loops(NULL, to_insert);
+}
+
+
+/* void patch_handler(...) is very similar to parts of the function patch_jumps. 
+   Its task is to redirect all jumps from the original head to the new head and
+   to redirect internal jumps inside the exception handler to the newly
+   created (copied) nodes.
+*/
+void patch_handler(struct LoopContainer *lc, basicblock *bptr, basicblock *original_head, basicblock *new_head)
+{
+       instruction *ip;
+       s4 *s4ptr;
+       void **tptr;
+       int high, low, count, i;
+
+       /* If node is not part of exception handler or has been visited, exit       */
+       if (!(bptr->lflags & HANDLER_PART) || (bptr->lflags & HANDLER_VISITED))
+               return;
+
+       /* mark block as visited                                                    */
+       bptr->lflags |= HANDLER_VISITED;
+
+       /* for all instructions in the copied block, do                             */
+       for (i = 0, ip = bptr->copied_to->iinstr; i < bptr->copied_to->icount; ++i, ++ip) {
+               switch (ip->opc) {
+               case ICMD_RETURN:
+               case ICMD_IRETURN:
+               case ICMD_LRETURN:
+               case ICMD_FRETURN:
+               case ICMD_DRETURN:
+               case ICMD_ARETURN:
+               case ICMD_ATHROW:
+                       break;                                 
+
+               case ICMD_IF_ICMPEQ:
+               case ICMD_IF_ICMPLT:
+               case ICMD_IF_ICMPLE:
+               case ICMD_IF_ICMPNE:
+               case ICMD_IF_ICMPGT:
+               case ICMD_IF_ICMPGE:
+                       
+               case ICMD_IF_LCMPEQ:
+               case ICMD_IF_LCMPLT:
+               case ICMD_IF_LCMPLE:
+               case ICMD_IF_LCMPNE:
+               case ICMD_IF_LCMPGT:
+               case ICMD_IF_LCMPGE:
+
+               case ICMD_IF_ACMPEQ:
+               case ICMD_IF_ACMPNE:
+
+               case ICMD_IFEQ:
+               case ICMD_IFNE:
+               case ICMD_IFLT:
+               case ICMD_IFGE:
+               case ICMD_IFGT:
+               case ICMD_IFLE:
+                               
+               case ICMD_IF_LEQ:
+               case ICMD_IF_LNE:
+               case ICMD_IF_LLT:
+               case ICMD_IF_LGE:
+               case ICMD_IF_LGT:
+               case ICMD_IF_LLE:
+
+               case ICMD_JSR:
+               case ICMD_IFNULL:
+               case ICMD_IFNONNULL:
+
+                       patch_handler(lc, bptr->next, original_head, new_head); 
+
+                       /* fall through */
+
+               case ICMD_GOTO:
+
+                       patch_handler(lc, ip->target, original_head, new_head);
+
+                       /* jumps to old header have to be redirected                        */
+                       if (((basicblock *) ip->target) == original_head)
+                               ip->target = (void *) new_head->copied_to;
+                       /* jumps to handler internal nodes have to be redirected            */
+                       else if (((basicblock *) ip->target)->lflags & HANDLER_PART)
+                               ip->target = (void *) ((basicblock *) ip->target)->copied_to;
+                       /* jumps to loop internal nodes have to be redirected               */
+                       else if (((basicblock *) ip->target)->lflags & LOOP_PART)
+                               ip->target = (void *) ((basicblock *) ip->target)->copied_to;
+                  
+                  
+                       break;
+                               
+               case ICMD_TABLESWITCH:
+                       {
+                               s4 *s4ptr, l, i;
+                               void **tptr;
+                               void **copy_ptr, **base_ptr;
+                               tptr = (void **) ip->target;
+                               s4ptr = ip->val.a;
+                               l = s4ptr[1];                          /* low                   */
+                               i = s4ptr[2];                          /* high                  */
+                               i = i - l + 1;
+                               
+                               copy_ptr = (void**) DMNEW(void*, i+1);
+                               base_ptr = (void*) copy_ptr;
+
+                               for (tptr = ip->target; i >= 0; --i, ++tptr, ++copy_ptr) {
+                                       patch_handler(lc, ((basicblock *) *tptr), original_head, new_head);
+                                       /* jumps to old header have to be redirected                */
+                                       if (((basicblock *) *tptr) == original_head)
+                                               copy_ptr[0] = (void *) new_head->copied_to;
+                                       /* jumps to handler internal nodes have to be redirected    */
+                                       else if (((basicblock *) *tptr)->lflags & HANDLER_PART)
+                                               copy_ptr[0] = (void *) ((basicblock *) tptr[0])->copied_to;
+                                       /* jumps to loop internal nodes have to be redirected       */
+                                       else if (((basicblock *) ip->target)->lflags & LOOP_PART)
+                                               copy_ptr[0] = (void *) ((basicblock *) tptr[0])->copied_to;
+                                       else
+                                               copy_ptr[0] = tptr[0];
+                                   }
+
+                               ip->target = base_ptr;
+                       }
+                       break;
+
+               case ICMD_LOOKUPSWITCH:
+                       {
+                               s4 i, l, val, *s4ptr;
+
+                               void **tptr;
+                               void **copy_ptr, **base_ptr;
+
+                               tptr = (void **) ip->target;
+                               s4ptr = ip->val.a;
+                               l = s4ptr[0];                          /* default               */
+                               i = s4ptr[1];                          /* count                 */
+
+                               copy_ptr = (void**) DMNEW(void*, i+1);
+                               base_ptr = (void*) copy_ptr;
+
+                               for (tptr = ip->target; i >= 0; --i, ++tptr, ++copy_ptr) {
+
+                                       patch_handler(lc, ((basicblock *) *tptr), original_head, new_head);
+                                       /* jumps to old header have to be redirected                */
+                                       if (((basicblock *) *tptr) == original_head)
+                                               copy_ptr[0] = (void *) new_head->copied_to;
+                                       /* jumps to handler internal nodes have to be redirected    */
+                                       else if (((basicblock *) *tptr)->lflags & HANDLER_PART)
+                                               copy_ptr[0] = (void *) ((basicblock *) tptr[0])->copied_to;
+                                       /* jumps to loop internal nodes have to be redirected       */
+                                       else if (((basicblock *) ip->target)->lflags & LOOP_PART)
+                                               copy_ptr[0] = (void *) ((basicblock *) tptr[0])->copied_to;
+                                       else
+                                               copy_ptr[0] = tptr[0];
+                                   }
+
+                               ip->target = base_ptr;
+                       }
+                       break;
+                               
+                   }   /* switch */
+                  
+           }       /* for    */
+
+               /* if fall through exits loop, goto is needed                           */
+               if (!(bptr->next->lflags & HANDLER_PART)) {
+                       bptr->copied_to->iinstr[bptr->copied_to->icount].opc = ICMD_GOTO;
+                       bptr->copied_to->iinstr[bptr->copied_to->icount].dst = NULL;
+                       bptr->copied_to->iinstr[bptr->copied_to->icount].target = bptr->next;
+                       bptr->copied_to->icount++;
+                       }               
+}
+
+
+/* This function copys the exception handler and redirects all jumps from the
+   original head to the new head in the original exception handler. All
+   redirection in the copied exception handler is done in patch_handler(...).
+*/
+void copy_handler(struct LoopContainer *lc, basicblock *bptr, basicblock *original_head, basicblock *new_head)
+{
+       instruction *ip;
+       s4 *s4ptr;
+       void **tptr;
+       int high, low, count, cnt;
+       struct LoopElement *le;
+       basicblock *new;
+
+       /* If this node has already been copied, return                             */
+       if (bptr->lflags & HANDLER_PART)
+               return;
+
+       /* The exception handler exists, when control flow enters loop again        */
+
+       if (bptr->lflags & LOOP_PART)
+               return;
+       for (le = lc->nodes; le != NULL; le = le->next) {
+               if (le->block == bptr) {
+                       printf("C_PANIC: should not happen\n");
+                       exit(-1);
+            }
+           }
+
+       /* mark block as part of handler                                            */
+       bptr->lflags |= HANDLER_PART;
+
+       /* copy node                                                                */
+       new = DMNEW(basicblock, 1);    
+       memcpy(new, bptr, sizeof(basicblock));
+       new->debug_nr = c_debug_nr++;
+
+       c_last_block_copied = new;
+
+       /* copy instructions and allow one more slot for possible GOTO              */
+       new->iinstr = DMNEW(instruction, bptr->icount + 1);
+       memcpy(new->iinstr, bptr->iinstr, bptr->icount*sizeof(instruction));
+
+       /* update original block                                                    */
+       bptr->copied_to = new;
+
+       /* append block to global list of basic blocks                              */
+       last_block->next = new;
+       last_block = new;
+       new->next = NULL;
+
+
+       /* find next block to copy, depending on last instruction of BB             */
+       if (bptr->icount == 0) {
+               copy_handler(lc, bptr->next, original_head, new_head);
+               return;
+           }
+
+       ip = bptr->iinstr + (bptr->icount - 1);
+       
+               switch (ip->opc) {
+               case ICMD_RETURN:
+               case ICMD_IRETURN:
+               case ICMD_LRETURN:
+               case ICMD_FRETURN:
+               case ICMD_DRETURN:
+               case ICMD_ARETURN:
+               case ICMD_ATHROW:
+                       break;                                 
+               
+               case ICMD_IFEQ:
+               case ICMD_IFNE:
+               case ICMD_IFLT:
+               case ICMD_IFGE:
+               case ICMD_IFGT:
+               case ICMD_IFLE:
+                       
+               case ICMD_IF_LCMPEQ:
+               case ICMD_IF_LCMPLT:
+               case ICMD_IF_LCMPLE:
+               case ICMD_IF_LCMPNE:
+               case ICMD_IF_LCMPGT:
+               case ICMD_IF_LCMPGE:
+                       
+               case ICMD_IF_LEQ:
+               case ICMD_IF_LNE:
+               case ICMD_IF_LLT:
+               case ICMD_IF_LGE:
+               case ICMD_IF_LGT:
+               case ICMD_IF_LLE:
+                       
+               case ICMD_IFNULL:
+               case ICMD_IFNONNULL:
+                       
+               case ICMD_IF_ICMPEQ:
+               case ICMD_IF_ICMPNE:
+               case ICMD_IF_ICMPLT:
+               case ICMD_IF_ICMPGE:
+               case ICMD_IF_ICMPGT:
+               case ICMD_IF_ICMPLE:
+               case ICMD_IF_ACMPEQ:
+               case ICMD_IF_ACMPNE:
+                       copy_handler(lc, bptr->next, original_head, new_head);
+                       /* fall through */
+         
+               case ICMD_GOTO:
+
+                       /* redirect jump from original_head to new_head                    */
+                       if ((basicblock *) ip->target == original_head)
+                               ip->target = (void *) new_head;
+                               
+                       copy_handler(lc, (basicblock *) (ip->target), original_head, new_head);
+                       
+                       break;
+         
+               case ICMD_TABLESWITCH:
+                       s4ptr = ip->val.a;
+                       tptr = (void **) ip->target;
+                       
+                       /* default branch */
+                       if (((basicblock *) *tptr) == original_head)
+                               tptr[0] = (void *) new_head;
+                       
+                       copy_handler(lc, (basicblock *) *tptr, original_head, new_head);
+                       
+                       s4ptr++;
+                       low = *s4ptr;
+                       s4ptr++;
+                       high = *s4ptr;
+                       
+                       count = (high-low+1);
+                       
+                       while (--count >= 0) {
+                               tptr++;
+                               /* redirect jump from original_head to new_head                 */
+                               if (((basicblock *) *tptr) == original_head)
+                                       tptr[0] = (void *) new_head;
+                               copy_handler(lc, (basicblock *) *tptr, original_head, new_head);
+                       }
+                       break;
+
+               case ICMD_LOOKUPSWITCH:
+                       s4ptr = ip->val.a;
+                       tptr = (void **) ip->target;
+                       
+                       /* default branch */
+                       if (((basicblock *) *tptr) == original_head)
+                               tptr[0] = (void *) new_head;
+                       
+                       copy_handler(lc, (basicblock *) *tptr, original_head, new_head);
+                       
+                       ++s4ptr;
+                       count = *s4ptr;
+                       
+                       while (--count >= 0) {
+                               ++tptr;
+                               /* redirect jump from original_head to new_head                 */
+                               if (((basicblock *) *tptr) == original_head)
+                                       tptr[0] = (void *) new_head;
+                               copy_handler(lc, (basicblock *) *tptr, original_head, new_head);
+                       }  
+                       break;
+
+               case ICMD_JSR:
+                       c_last_target = bptr;
+                       copy_handler(lc, (basicblock *) (ip->target), original_head, new_head);         
+                       break;
+                       
+               case ICMD_RET:
+                       copy_handler(lc, c_last_target->next, original_head, new_head);
+                       break;
+                       
+               default:
+                       copy_handler(lc, bptr->next, original_head, new_head);
+                       break;  
+                   } 
+           
+}           
+
+
+/* If a loop is duplicated, all exceptions, that are contained in this loops' body
+   have to be duplicated as well. The following function together with the
+   two helper functions copy_handler and patch_handler perform this task.
+*/
+void update_internal_exceptions(struct LoopContainer *lc, basicblock *original_head, basicblock *new_head)
+{
+       xtable *ex, *new;
+       struct LoopContainer *l;
+
+       /* Bottom of tree reached -> return                                         */
+       if (lc == NULL)
+               return;
+
+       /* Call update_internal for all nested (=child) loops                       */
+       l = lc->tree_down;
+       while (l != NULL) {
+               update_internal_exceptions(l, original_head, new_head);
+               l = l->tree_right;
+           }
+
+       /* For all exceptions of this loop, do                                      */
+       ex = lc->exceptions;
+       while (ex != NULL) {
+               
+               /* Copy the exception and patch the jumps                               */
+               copy_handler(lc, ex->handler, original_head, new_head);
+               patch_handler(lc, ex->handler, original_head, new_head);                
+
+               /* Insert a new exception into the global exception table               */
+               new = DMNEW(xtable, 1);
+               memcpy(new, ex, sizeof(xtable));
+
+               /* Increase number of exceptions                                        */
+               ++exceptiontablelength;
+
+               ex->next = new;
+               ex->down = new;
+
+               /* Set new start and end point of this exception                        */
+               new->start = ex->start->copied_to;
+               new->end = ex->end->copied_to;
+
+               /* Set handler pointer to copied exception handler                      */
+               new->handler = ex->handler->copied_to;
+
+               ex = new->next;
+           }
+
+}
+
+/* If a loop is duplicated, all exceptions that contain this loop have to be
+   extended to the copied nodes as well. The following function checks for
+   all exceptions of all parent loops, whether they contain the loop pointed to
+   by lc. If so, the exceptions are extended to contain all newly created nodes.
+*/
+void update_external_exceptions(struct LoopContainer *lc, int loop_head)
+{
+       xtable *ex, *new;
+
+       /* Top of tree reached -> return                                            */
+       if (lc == NULL)
+               return;
+       
+       ex = lc->exceptions;
+
+       /* For all exceptions of this loop do                                       */
+       while (ex != NULL) {
+                  
+               /* It is possible that the loop contains exceptions that do not protect */
+               /* the loop just duplicated. It must be checked, if this is the case    */
+               if ((loop_head >= block_index[ex->startpc]) && (loop_head < block_index[ex->endpc])) {
+
+                       /* loop is really inside exception, so create new exception entry   */
+                       /* in global exception list                                         */
+                       new = DMNEW(xtable, 1);
+                       memcpy(new, ex, sizeof(xtable));
+
+
+                       /* Increase number of exceptions                                    */
+                       ++exceptiontablelength;
+
+                       ex->next = new;
+                       ex->down = new;
+
+                       /* Set new start and end point of this exception                    */
+                       new->start = c_first_block_copied;
+                       new->end = c_last_block_copied;
+
+                       ex = new->next;
+               }
+               /* exception does not contain the duplicated loop -> do nothing         */
+               else
+                       ex = ex->next;
+           }
+
+       /* Call update_external for parent node                                     */
+       update_external_exceptions(lc->parent, loop_head);
+}
+       
+
+
+/*     This function is needed to insert the static checks, stored in c_constraints
+       into the intermediate code.
+*/
+void create_static_checks(struct LoopContainer *lc)
+{
+       int i, j, stackdepth, cnt;
+       struct Changes **c;
+       struct Constraint *tc1, *tc2;
+       struct LoopElement *le; 
+
+       /* loop_head points to the newly inserted loop_head, original_start to      */
+       /* the old loop header                                                      */
+       basicblock *bptr, *loop_head, *original_start, *temp;
+       instruction *inst, *tiptr;
+
+       /* tos and newstack are needed by the macros, that insert instructions into */
+       /* the new loop head                                                        */
+       stackptr newstack, tos, sptr;
+       xtable *ex;
+
+#ifdef STATISTICS
+       /* show_loop_statistics(); */ 
+#endif
+
+       loop_head = &block[c_current_head];
+       c_first_block_copied = c_last_block_copied = NULL;
+
+       /* the loop nodes are copied                                                */
+       le = lc->nodes;
+       while (le != NULL)
+       {
+               bptr = DMNEW(basicblock, 1);    
+               memcpy(bptr, le->block, sizeof(basicblock));
+               bptr->debug_nr = c_debug_nr++;
+
+               /* determine beginning of copied loop to extend exception handler, that */
+               /* protect this loop                                                    */
+               if (c_first_block_copied == NULL)
+                       c_first_block_copied = bptr;
+
+               /* copy instructions and add one more slot for possible GOTO            */
+               bptr->iinstr = DMNEW(instruction, bptr->icount + 1);
+
+               memcpy(bptr->iinstr, le->block->iinstr, (bptr->icount+1)*sizeof(instruction));
+
+               le->block->copied_to = bptr;
+
+               /* add block to global list of BBs                                      */
+               last_block->next = bptr;
+               last_block = bptr;
+               bptr->next = NULL;
+
+               node_into_parent_loops(lc->parent, bptr);
+               le = le->next;
+       }
+
+       c_last_block_copied = bptr;
+
+       /* create an additional basicblock for dynamic checks                       */
+       original_start = bptr = DMNEW(basicblock, 1);    
+
+       /* copy current loop header to new basic block                              */
+       memcpy(bptr, loop_head, sizeof(basicblock));
+    bptr->debug_nr = c_debug_nr++;
+
+       /* insert the new basic block and move header before first loop node        */
+       le = lc->nodes;
+       temp = le->block;
+
+       /* if header is first node of loop, insert original header after it         */
+       if (temp == loop_head)
+               loop_head->next = bptr;
+       else {
+       /* else, we have to find the predecessor of loop header                     */
+               while (temp->next != loop_head)
+                       temp = temp->next;
+
+               /* insert original header after newly created block                     */
+               temp->next = bptr;
+
+               /* if predecessor is not loop part, insert a goto                       */
+               if (!(temp->lflags & LOOP_PART)) {
+
+                       /* copy instructions and add an additional slot                     */
+                       tiptr = DMNEW(instruction, temp->icount + 1);
+                       memcpy(tiptr, temp->iinstr, sizeof(instruction)*temp->icount);
+                       
+                       temp->iinstr = tiptr;
+                       tiptr = temp->iinstr + temp->icount;
+                       
+                       /* add goto to loop header. If node is part of exception handler    */
+                       /* jmp is automagically redirected during patch_handler and works   */
+                       /* correct                                                          */
+                       tiptr->opc = ICMD_GOTO;
+                       tiptr->dst = NULL;
+                       tiptr->target = (void*) loop_head;
+                       
+                       ++temp->icount;
+                   }
+               
+               
+               temp = block;
+               /* if first loop block is first BB of global list, insert loop_head at  */
+               /* beginning of global BB list                                          */
+               if (temp == le->block) {
+                       if (c_newstart == NULL) {
+                               c_needs_redirection = true;
+                               c_newstart = loop_head;
+                               loop_head->next = block;
+                           }
+                       else {
+                               loop_head->next = c_newstart;
+                               c_newstart = loop_head;
+                           }
+                   }
+               else {
+          
+                       while (temp->next != le->block)
+                               temp = temp->next;
+
+                       loop_head->next = temp->next;
+                       temp->next = loop_head;
+               
+                       /* to be on the safe side insert a jump from the previous instr     */
+                       /* over thr new inserted node                                       */
+       
+                       /* special case - jump from node to loop_head: then remove          */
+                       /* goto / happens rather often due to loop layout                   */
+                       tiptr = temp->iinstr + (temp->icount-1);
+               
+                       if ((tiptr->opc == ICMD_GOTO) && (tiptr->target == loop_head)) {
+                               tiptr->opc = ICMD_NOP;
+                               tiptr->dst = NULL;
+                       }
+                       else {
+
+                               tiptr = DMNEW(instruction, temp->icount + 1);
+                               memcpy(tiptr, temp->iinstr, sizeof(instruction)*temp->icount);
+
+                               temp->iinstr = tiptr;
+                               tiptr = temp->iinstr + temp->icount;
+
+                               tiptr->opc = ICMD_GOTO;
+                               tiptr->dst = NULL;
+                               tiptr->target = (void*) loop_head->next;
+
+                               ++temp->icount;
+                   }
+                   }
+           }
+
+       /* adjust exceptions                                                        */
+       ex = extable;
+       while (ex != NULL) {
+
+               /* if an exception covers whole loop and starts at first loop node, it  */
+               /* has to be extended to cover the new first node as well               */
+               if (ex->start == le->block) {
+                       
+                       if ((lc->loop_head >= block_index[ex->startpc]) && (lc->loop_head < block_index[ex->endpc])) 
+                               ex->start = loop_head;
+                   }
+
+               /* an exception that ended at the old loop header now must contains the */
+               /* new loop header as well                                              */
+               if (ex->end == loop_head)
+                       ex->end = original_start;
+
+               ex = ex->down;
+           }
+       
+
+       /* insert new header node into nodelists of all enclosing loops             */
+       header_into_parent_loops(lc, loop_head, original_start, le->block);
+
+       /* prepare instruction array to insert checks                               */
+       inst = loop_head->iinstr = DMNEW(instruction, c_needed_instr + 2); 
+       loop_head->icount = c_needed_instr + 1;
+
+       /* init instruction array                                                   */
+       for (cnt=0; cnt<c_needed_instr + 1; ++cnt) {
+               inst[0].opc = ICMD_NOP;
+               inst[0].dst = NULL;
+           }
+
+       loop_head->copied_to = NULL; 
+
+       /* prepare stack                                                            */
+       loop_head->instack = copy_stack_from(bptr->instack);
+       loop_head->outstack = copy_stack_from(bptr->instack);
+       
+       tos = loop_head->instack;
+       stackdepth = loop_head->indepth;
+       
+       /* step through all inserted checks and create instructions for them        */
+       for (i=0; i<maxlocals+1; ++i)
+       {
+               tc1 = c_constraints[i];
+               while (tc1 != NULL)
+               {
+                       switch (tc1->type)
+                       {
+                       
+                               /* check a variable against a constant                          */
+                       case TEST_ZERO:
+                       case TEST_UNMOD_ZERO: 
+
+#ifdef LOOP_DEBUG
+                               printf("insert ZERO-test\n");
+                               fflush(stdout);
+#endif
+
+                               /* optimize if tc1->varRef >= tc1->constant                     */
+                               LOAD_VAR(tc1->varRef);
+                               LOAD_CONST(tc1->constant);
+                               GOTO_NOOPT_IF_LT;
+                               break;
+
+                               /* check a variable against an array length                     */
+                       case TEST_ALENGTH:       
+                       case TEST_UNMOD_ALENGTH:
+                               
+                               /* optimize if                                                  */
+                               /* tc1->varRef + tc1->constant < lengthOf(tc1->arrayRef)        */
+#ifdef LOOP_DEBUG
+                               printf("insert ALENGTH-test\n");
+                               fflush(stdout);
+#endif
+
+                               LOAD_VAR(tc1->varRef);
+                               LOAD_CONST(tc1->constant);
+                               ADD;
+                               LOAD_ARRAYLENGTH(tc1->arrayRef);
+                               GOTO_NOOPT_IF_GE;
+                               break;
+                               
+                               /* test right side of comparison against constant               */
+                       case TEST_RS_ZERO:      
+
+#ifdef LOOP_DEBUG
+                               printf("insert RS-ZERO-test\n");
+                               fflush(stdout);
+#endif
+
+                               /* optimize if right-side >= tc1->constant                      */
+                               LOAD_RIGHT_SIDE;
+                               LOAD_CONST(tc1->constant);
+                               GOTO_NOOPT_IF_LT;
+                               break;
+                               
+                               /* test right side of comparison against array length           */
+                       case TEST_RS_ALENGTH: 
+
+#ifdef LOOP_DEBUG
+                               printf("insert RS-ALENGTH-test\n");
+                               fflush(stdout);
+#endif
+                               /* optimize if right-side < lengthOf(arrayRef)                  */
+                               LOAD_RIGHT_SIDE;
+                               LOAD_ARRAYLENGTH(tc1->arrayRef);
+                               GOTO_NOOPT_IF_GT;
+                               break;
+                               
+                               /* test unmodified variable against arraylength                 */
+                       case TEST_CONST_ALENGTH:
+
+#ifdef LOOP_DEBUG
+                               printf("insert CONST ALENGTH-test\n");
+                               fflush(stdout);
+#endif
+
+                               /* optimize if tc1->constant < lengthOf(tc1->arrayRef)          */
+                               LOAD_CONST(tc1->constant);
+                               LOAD_ARRAYLENGTH(tc1->arrayRef);
+                               GOTO_NOOPT_IF_GE;
+                               break;              
+                       }
+                       
+                       tc1 = tc1->next;
+               }
+               c_constraints[i] = NULL;
+       }
+   
+       /* if all tests succeed, jump to optimized loop header                      */
+       if (loop_head->next != original_start) {
+               inst->opc = ICMD_GOTO;
+               inst->dst = NULL;
+               inst->target = original_start;
+           }
+
+       /* redirect jumps from original loop head to newly inserted one             */
+       patch_jumps(original_start, loop_head, lc); 
+
+       /* if exceptions have to be correct due to loop duplication these two       */
+       /* functions perform this task.                                             */
+       update_internal_exceptions(lc, loop_head, original_start);
+       update_external_exceptions(lc->parent, lc->loop_head);
+        
+}
+
+
+/*     This function performs an update between two arrays of struct Changes (that
+       reflect variable changes). The merge is performed unrstricted in the way, that
+       all variable changes in c1 took place in a nested loop and therefore are
+       considered to be without limit. Beside that, the merge is a simple union of the
+       changes recorded in both arrays. A variable, which limits are undefinied, is
+       represented by its lower bound being higher than the upper bound. The result 
+       of the union is stored in c1.
+*/
+struct Changes ** constraints_unrestricted_merge(struct Changes **c1, struct Changes **c2)
+{
+       int i, changed;
+
+       if ((c1 == NULL) || (c2 == NULL))
+               printf("C_ERROR: debugging error 0x03\n");
+
+       changed = 0;
+       for (i=0; i<maxlocals; ++i) {
+               if (c1[i] == NULL) {
+                       if (c2[i] != NULL) {            /* a change in c2 is updated in c1              */
+                               changed = 1;
+                               c1[i] = c2[i];
+                               c1[i]->lower_bound = c1[i]->upper_bound+1;
+                               }
+                       }
+               else {
+                       if (c1[i]->lower_bound > c1[i]->upper_bound)
+                               continue;                               /* variable's bounds already undefined  */
+
+                       if (c2[i] == NULL) {            /* variable changed in c1 -> now undef. */
+                               changed = 1;
+                               c1[i]->lower_bound = c1[i]->upper_bound+1;
+                               }
+                       else {
+                               if ((c1[i]->lower_bound == c2[i]->lower_bound) &&
+                                       (c1[i]->upper_bound == c2[i]->upper_bound))
+                                       continue;                       /* variable's bounds remain the same    */
+                               else {
+                                       changed = 1;
+                                       c1[i]->lower_bound = c1[i]->upper_bound+1;
+                                       }                                       /* variable changed in c1 -> now undef. */
+                               }
+                       }
+               }
+       
+       if (changed)
+               return c1;
+       else
+               return NULL;
+}
+
+/*     This function performs an update between two arrays of struct Changes (that
+       reflect variable changes). The merge is a simple union of the bounds
+       changes recorded in both arrays. A variable, which limits are undefinied, is
+       represented by its lower bound being higher than the upper bound. The result 
+       of the union is stored in c1.
+*/
+struct Changes ** constraints_merge(struct Changes **c1, struct Changes **c2)
+{
+       int i, changed;
+
+       if ((c1 == NULL) || (c2 == NULL))
+               printf("C_ERROR: debugging error 0x04\n");
+
+       changed = 0;
+
+       for (i=0; i<maxlocals; ++i) {
+               if (c1[i] == NULL) {
+                       if (c2[i] != NULL) {            /* update changes in c2 in c1                   */
+                               if ((c1[i] = (struct Changes *) malloc (sizeof(struct Changes))) == NULL)
+                                       c_mem_error();
+
+                                       c1[i]->lower_bound = c2[i]->lower_bound; 
+                                       c1[i]->upper_bound = c2[i]->upper_bound;
+                                       changed = 1;
+                               }       
+               }
+               else {
+                       if (c2[i] != NULL) {
+
+                               if (c1[i]->lower_bound > c1[i]->upper_bound)
+                                       continue;                       /* var in c1 is unrestricted                    */
+
+                               if (c1[i]->lower_bound > c2[i]->lower_bound) {
+                                       c1[i]->lower_bound = c2[i]->lower_bound;
+                                       changed = 1;            /* write new lower bound                                */
+                                       }
+                               if (c1[i]->upper_bound < c2[i]->upper_bound) {
+                                       c1[i]->upper_bound = c2[i]->upper_bound;
+                                       changed = 1;            /* write new higher bound                               */
+                                       }
+                               }
+                       }
+               }
+
+       if (changed)
+               return c1;
+       else
+               return NULL;
+}
+
+
+/*     This function simply copies an array of changes 
+*/
+struct Changes** constraints_clone(struct Changes **c)
+{
+       int i;
+       struct Changes **t;
+       
+       if ((t = (struct Changes **) malloc(maxlocals * sizeof(struct Changes *))) == NULL)
+               c_mem_error();
+
+       for (i=0; i<maxlocals; ++i) {           /* for all array elements (vars) do             */
+               if (c[i] == NULL)
+                       t[i] = NULL;
+               else {
+                       if ((t[i] = (struct Changes *) malloc(sizeof(struct Changes))) == NULL)
+                               c_mem_error();
+                       t[i]->lower_bound = c[i]->lower_bound;
+                       t[i]->upper_bound = c[i]->upper_bound;
+                       }
+               }
+       
+       return t;
+}
+
+/*     This function is used to reset the changes of a variable to the time, it was
+       pushed onto the stack. If a variable has been modified between an instruction
+       and a previous push onto the stack, its value in the changes array does not
+       correctly reflect its bounds the time, it was pushed onto the stack. This 
+       function corrects the situation.
+       */
+struct Changes* backtrack_var(int node, int from, int to, int varRef, struct Changes *changes)
+{
+       struct Changes *tmp;
+       basicblock bp;
+       instruction *ip;
+       struct Trace *t;
+
+       if (changes == NULL)    /* if there are no changes, immediately return          */
+               return NULL;
+       else {                                  /* init a Changes structure with current values         */
+               if ((tmp = (struct Changes *) malloc(sizeof(struct Changes))) == NULL)
+                       c_mem_error();
+               
+               tmp->upper_bound = changes->upper_bound;
+               tmp->lower_bound = changes->lower_bound;
+               }
+
+       if (tmp->upper_bound < tmp->lower_bound)
+               return tmp;                     /* if it is unrestricted no backtracking can happen     */
+
+       bp = block[node];
+       ip = bp.iinstr + to;
+
+       for (; from < to; --to, --ip) {         /* scan instructions backwards                  */
+               switch (ip->opc) {
+               case ICMD_IINC:                                 /* a var has been modified                              */
+                       if (varRef != ip->op1)          /* not the one, we are interested in    */
+                               break;
+                       tmp->upper_bound -= ip->val.i;          /* take back modifications              */
+                       tmp->lower_bound -= ip->val.i;
+                       break;
+
+               case ICMD_ISTORE:                               /* a var has been modified                              */
+                       if (varRef != ip->op1)          /* not the one, we are interested in    */
+                               break;
+
+                       /* it is our variable, so trace its origin                                                      */
+                       t = tracing(&block[node],to, 0);                
+       
+                       switch (t->type) {
+                               case TRACE_IVAR:  
+                                       if ((t->var = ip->op1) && (t->neg > 0)) {
+                                               /* it was the same var -> take back modifications               */
+                                               tmp->upper_bound -= t->constant;
+                                               tmp->lower_bound -= t->constant;
+                                               }               
+                                       else
+                                               tmp->lower_bound = tmp->upper_bound+1;  /* unknown              */
+                                       break;
+
+                               /* cannot restore it -> invalidate t                                                    */
+                               case TRACE_ICONST:
+                               case TRACE_ALENGTH:   
+                               case TRACE_UNKNOWN: 
+                               case TRACE_AVAR: 
+                                       tmp->lower_bound = tmp->upper_bound+1;   
+                                       break;
+                               }
+
+                       break;
+                       }
+               }
+       return tmp;
+}
+
+/*     This function performs the main task of bound check removal. It removes
+       all bound-checks in node. change is a pointer to an array of struct Changes
+       that reflect for all local variables, how their values have changed from
+       the start of the loop. The special flag is needed to deal with the header
+       node.
+*/
+void remove_boundchecks(int node, int from, struct Changes **change, int special)
+{
+       basicblock bp;
+       instruction *ip;
+       int i, j, count, ignore, degrade_checks, opt_level;
+       struct depthElement *d;
+       struct Changes **t1, **t2, **tmp, *t;
+       struct Trace *t_array, *t_index;
+
+       /* printf("remove_bc called: %d - %d - %d\n", node, from, special);                     */
+          
+       /* a flag, that is set, when previous optimzations have to be taken back        */
+       degrade_checks = 0;                     
+
+       if (c_current_loop[node] > 0) {         /* this node is part of the loop                */
+               if (c_current_loop[node] > 1) { /* it is not the header node                    */
+
+                       /* get variable changes, already recorded for this node                         */
+                       t1 = c_dTable[node]->changes;
+                       
+                       if (t1 != NULL) {                       /* it is not the first visit                    */
+                               if ((c_nestedLoops[node] != c_current_head) && (c_nestedLoops[node] == c_nestedLoops[from])) {
+                               /* we are looping in a nested loop, so made optimizations               */
+                               /* need to be reconsidered                                                                              */
+                                       degrade_checks = 1;
+                                       if (constraints_unrestricted_merge(t1, change) == NULL) 
+                                               return;                 /* no changes since previous visit              */
+                                               /* if there have been changes, they are updated by              */
+                                               /* constraints_unrestricted_merge in t1                                 */
+                                       }
+                               else {
+                                       if (constraints_merge(t1, change) == NULL)
+                                               return;                 /* no changes since previous visit              */
+                                               /* if there have been changes, they are updated by              */
+                                               /* constraints_merge in t1                                                              */
+                                       }
+                               }
+                       else {                                          /* first visit                                                  */
+                               /* printf("first visit - constraints cloned\n");                                */
+                               c_dTable[node]->changes = constraints_clone(change);
+                               }
+
+                       /* tmp now holds a copy of the updated variable changes                         */
+                       tmp = constraints_clone(c_dTable[node]->changes);       
+                       }
+               else if (special) {                             /* header and need special traetment    */
+                       /* printf("special treatment called\n");                                                        */
+                       /* tmp now holds a copy of the current new variable changes                     */
+                       tmp = constraints_clone(change);
+                       }
+               else
+                       return;
+
+               bp = block[node];                               /* scan all instructions                                */
+               count = bp.icount;
+               ip = bp.iinstr;
+               ignore = 0;
+
+               for (i=0; i<count; ++i, ++ip) {
+                       switch (ip->opc) {
+                       case ICMD_IASTORE:                      /* found an array store                                 */
+                       case ICMD_LASTORE:          
+                       case ICMD_FASTORE:          
+                       case ICMD_DASTORE:          
+                       case ICMD_AASTORE:          
+                       case ICMD_BASTORE:          
+                       case ICMD_CASTORE:          
+                       case ICMD_SASTORE:
+
+                               t_index = tracing(&bp, i-1, 1); /* get index                                    */
+                               t_array = tracing(&bp, i-1, 2); /* get array refernce                   */
+                               ignore = 1;
+                               /* fall through */
+
+                       case ICMD_IALOAD:                       /* found an array load                                  */
+                       case ICMD_LALOAD:       
+                       case ICMD_FALOAD:
+                       case ICMD_DALOAD:
+                       case ICMD_AALOAD:
+                       case ICMD_BALOAD:
+                       case ICMD_CALOAD:
+                       case ICMD_SALOAD:
+                               if (!ignore) {
+                                       t_index = tracing(&bp, i-1, 0); /* get index                            */
+                                       t_array = tracing(&bp, i-1, 1); /* get array refernce           */
+                                       ignore = 0;
+                                       }
+
+                               /* printf("Array access with params:\n");
+                               printf("Array:\n");
+                               show_trace(t_array);
+                               printf("Index:\n");
+                               show_trace(t_index);
+                               */
+
+#ifdef STATISTICS
+                               if (ip->op1 == OPT_UNCHECKED) {         /* found new access                     */
+                                  c_stat_array_accesses++;
+                                  ip->op1 = OPT_NONE;
+                                  c_stat_no_opt++;
+                                  }
+#endif
+
+                               /* can only optimize known arrays that do not change                    */
+                               if ((t_array->type != TRACE_AVAR) || (c_var_modified[t_array->var])) 
+                                       break;
+                               
+                               switch (t_index->type) {        /* now we look at the index                     */
+                               case TRACE_ICONST:                      /* it is a constant value or an         */
+                               case TRACE_ALENGTH:                     /* array length                                         */
+#ifdef STATISTICS
+                                       switch (ip->op1) {              /* take back old optimzation            */
+                                       case OPT_UNCHECKED:
+                                               break;
+                                       case OPT_NONE:
+                                               c_stat_no_opt--;
+                                               break;
+                                       case OPT_FULL:
+                                               c_stat_full_opt--;
+                                               break;
+                                       case OPT_UPPER:
+                                               c_stat_upper_opt--;
+                                               break;
+                                       case OPT_LOWER:
+                                               c_stat_lower_opt--;
+                                               break;
+                                               }
+#endif
+                                       if (degrade_checks)             /* replace existing optimization        */
+                                               ip->op1 = insert_static(t_array->var, t_index, NULL, special);
+                                       else {
+                                               /* Check current optimization and try to improve it     by      */
+                                               /* inserting new checks                                                                 */
+                                               switch (ip->op1) {      
+                                               case OPT_UNCHECKED:
+                                                       ip->op1 = insert_static(t_array->var, t_index, NULL, special);
+                                                       break;
+                                               case OPT_NONE:          
+                                                       ip->op1 = insert_static(t_array->var, t_index, NULL, special);
+                                                       break;
+                                               case OPT_UPPER:         
+                                                       opt_level = insert_static(t_array->var, t_index, NULL, special);
+                                                       if ((opt_level == OPT_FULL) || (opt_level == OPT_LOWER))
+                                                               ip->op1 = OPT_FULL;
+                                                       break;
+                                               case OPT_LOWER: 
+                                                       opt_level = insert_static(t_array->var, t_index, NULL, special);
+                                                       if ((opt_level == OPT_FULL) || (opt_level == OPT_UPPER))
+                                                               ip->op1 = OPT_FULL;
+                                                       break;
+                                               case OPT_FULL:
+#ifdef STATISTICS
+                                                       c_stat_full_opt++;
+#endif
+                                                       break;
+                                                       }
+                                               }
+                                       break;
+
+                               case TRACE_IVAR:                        /* it's a variable                                      */
+
+                                       /* if the variable is changed between its usage as an index     */
+                                       /* of the array access and its push onto the stack, we have     */
+                                       /* to set the changes back to the time, it is pushed onto       */
+                                       /* the stack as an index variable.                                                      */
+                                       t = backtrack_var(node, t_index->nr, i-1, t_index->var, tmp[t_index->var]);
+#ifdef STATISTICS
+                                       switch (ip->op1) {              /* take back old optimzation            */
+                                       case OPT_UNCHECKED:
+                                               break;
+                                       case OPT_NONE:
+                                               c_stat_no_opt--;
+                                               break;
+                                       case OPT_FULL:
+                                               c_stat_full_opt--;
+                                               break;
+                                       case OPT_UPPER:
+                                               c_stat_upper_opt--;
+                                               break;
+                                       case OPT_LOWER:
+                                               c_stat_lower_opt--;
+                                               break;
+                                               }
+#endif
+                                       if (degrade_checks)
+                                               ip->op1 = insert_static(t_array->var, t_index, t, special);
+                                       else {
+                                               /* Check current optimization and try to improve it     by      */
+                                               /* insert new check. t reflects var changes for index   */
+                                               switch (ip->op1) {
+                                               case OPT_UNCHECKED:
+                                                       ip->op1 = insert_static(t_array->var, t_index, t, special);
+                                                       break;
+                                               case OPT_NONE:
+                                                       ip->op1 = insert_static(t_array->var, t_index, t, special);
+                                                       break;
+                                               case OPT_UPPER:
+                                                       opt_level = insert_static(t_array->var, t_index, t, special);
+                                                       if ((opt_level == OPT_FULL) || (opt_level == OPT_LOWER))
+                                                               ip->op1 = OPT_FULL;
+                                                       break;
+                                               case OPT_LOWER: 
+                                                       opt_level = insert_static(t_array->var, t_index, t, special);
+                                                       if ((opt_level == OPT_FULL) || (opt_level == OPT_UPPER))
+                                                               ip->op1 = OPT_FULL;
+                                                       break;
+                                               case OPT_FULL:
+#ifdef STATISTICS
+                                                       c_stat_full_opt++;
+#endif
+                                                       break;
+                                                       }
+                                               }
+                                       break;
+
+                               case TRACE_UNKNOWN: 
+                               case TRACE_AVAR:    
+                                       break;
+                                       }
+                               break;
+               
+                       case ICMD_ISTORE:               /* an integer value is stored                           */
+                               t_index = tracing(&bp, i-1, 0); /* trace back its origin                */
+
+                               /* the struct Changes for this variable needs to be updated             */
+                               t = tmp[ip->op1];
+                               if (t == NULL) {        /* if it's the first one, create new entry      */
+                                       if ((t = (struct Changes *) malloc(sizeof(struct Changes))) == NULL)
+                                               c_mem_error();
+                                       t->upper_bound = t->lower_bound = 0;
+                                       tmp[ip->op1] = t;
+                                       }
+
+                               switch (t_index->type) {                /* check origin of store                */
+
+                               case TRACE_ICONST:      /* constant -> set bounds to const value        */
+                                       t->upper_bound = t->lower_bound = t_index->constant;
+                                       break;  
+
+                               case TRACE_IVAR:        /* if it's the same variable, update consts     */  
+                                       if ((t_index->var = ip->op1) && (t_index->neg > 0)) {
+                                               t->upper_bound += t_index->constant;
+                                               t->lower_bound += t_index->constant;
+                                               }
+                                       else
+                                               t->lower_bound = t->upper_bound+1;
+                                       break;
+
+                               case TRACE_ALENGTH:   /* else -> unknown                                                */
+                               case TRACE_UNKNOWN: 
+                               case TRACE_AVAR: 
+                                       t->lower_bound = t->upper_bound+1;   
+                                       break;
+                                       }
+
+                               break;
+
+                       case ICMD_IINC:                 
+
+                               /* the struct Changes for this variable needs to be updated             */
+                               if ((t = tmp[ip->op1]) == NULL) {       /* first one -> create new      */
+                                       if ((t = (struct Changes *) malloc(sizeof(struct Changes))) == NULL)
+                                               c_mem_error();
+                                       t->upper_bound = t->lower_bound = ip->val.i;
+                                       tmp[ip->op1] = t;
+                                       }  
+                               else {                          /* update changes, made by iinc                         */
+                                       t->upper_bound += ip->val.i;
+                                       t->lower_bound += ip->val.i;
+                                       }
+                               break;
+                               }       /* switch */
+                       }               /* for    */
+               
+               if (!special) {                         /* we are not interested in only the header     */
+                       d = c_dTable[node];
+                       while (d != NULL) {             /* check all sucessors of current node          */
+                               remove_boundchecks(d->value, node, tmp, special);       
+                               d = d->next;
+                               }
+                       }
+           }   /* if */
+}
+
+/*     This function calls the bound-check removal function for the header node
+       with a special flag. It is important to notice, that no dynamic 
+       constraint hold in the header node (because the comparison is done at
+       block end).
+*/
+void remove_header_boundchecks(int node, struct Changes **changes)
+{
+       remove_boundchecks(node, -1, changes, BOUNDCHECK_SPECIAL);
+}
+
+/*     Marks all basicblocks that are part of the loop
+*/
+void mark_loop_nodes(struct LoopContainer *lc)
+{
+       struct LoopElement *le = lc->nodes;
+
+       while (le != NULL) {
+               le->block->lflags |= LOOP_PART;
+               le = le->next;
+               }
+}
+
+/*     Clears mark for all basicblocks that are part of the loop
+*/
+void unmark_loop_nodes(struct LoopContainer *lc)
+{
+       struct LoopElement *le = lc->nodes;
+
+       while (le != NULL) {
+               le->block->lflags = 0;
+               le = le->next;
+               }
+}
+
+
+/*     This function performs the analysis of code in detected loops and trys to
+       identify array accesses suitable for optimization (bound check removal). The
+       intermediate code is then modified to reflect these optimizations.
+*/
+void optimize_single_loop(struct LoopContainer *lc)
+{
+       struct LoopElement *le;
+       struct depthElement *d;
+       int i, head, node;
+       struct Changes **changes;
+
+       if ((changes = (struct Changes **) malloc(maxlocals * sizeof(struct Changes *))) == NULL)
+               c_mem_error();
+
+    head = c_current_head = lc->loop_head;
+       c_needed_instr = c_rs_needed_instr = 0;
+
+       /* init array for null ptr checks */
+       for (i=0; i<maxlocals; ++i) 
+               c_null_check[i] = 0;
+
+
+       /* don't optimize root node (it is the main procedure, not a loop)                      */
+       if (head < 0)
+               return;
+
+       /* setup variables with initial values                                                                          */
+       c_loopvars = NULL;
+       for (i=0; i < block_count; ++i) {
+               c_toVisit[i] = 0;
+               c_current_loop[i] = -1;
+               if ((d = c_dTable[i]) != NULL)
+                       d->changes = NULL;
+               }
+
+       for (i=0; i < maxlocals; ++i) {
+               c_var_modified[i] = 0;
+               if (changes[i] != NULL) {
+                       changes[i] = NULL;
+                       printf("C_PANIC 1\n");
+                       }
+               }
+
+       for (i=0; i < (maxlocals+1); ++i) {
+               if (c_constraints[i] != NULL) {
+                   c_constraints[i] = NULL;
+                       printf("C_PANIC 2\n");
+                       }
+               }
+
+       le = lc->nodes;
+       while (le != NULL) {
+               node = le->node;
+
+               if (node == head)
+                       c_current_loop[node] = 1;   /* the header node gets 1               */
+               else if (c_nestedLoops[node] == head)
+                       c_current_loop[node] = 2;       /* top level nodes get 2                                */
+               else
+                       c_current_loop[node] = 3;       /* nodes, part of nested loop get 3             */
+               
+               c_toVisit[node] = 1;
+               le = le->next;
+               }
+
+       /* After setup work has been performed, start to analyse                                        */
+#ifdef LOOP_DEBUG
+       printf("****** Starting analysis (%d)******\n", head);                  
+       fflush(stdout);
+#endif
+
+       if (analyze_for_array_access(head) > 0) {/* loop contains array access          */
+
+#ifdef LOOP_DEBUG
+               printf("analyze for array access finished and found\n");        
+               fflush(stdout);
+#endif
+
+               /* for performance reasons the list of all interesting loop vars is             */
+               /* scaned and for all modified vars a flag in c_var_modified is set             */
+               scan_global_list();                                     
+
+#ifdef LOOP_DEBUG
+               printf("global list scanned\n");
+               fflush(stdout);
+#endif
+
+               /* if the loop header contains or-conditions or an index variable               */
+               /* is modified in the catch-block within the loop, a conservative               */
+               /* approach is taken and optimizations are cancelled                                    */
+               if (analyze_or_exceptions(head, lc) > 0) {
+
+#ifdef LOOP_DEBUG
+                       printf("Analyzed for or/exception - no problems \n");            
+                       fflsuh(stdout);
+#endif
+
+                       init_constraints(head); /* analyze dynamic bounds in header                     */
+                       /* show_right_side();                                                                                           */
+
+                       if (c_rightside == NULL)
+                               return;
+
+                       /* single pass bound check removal - for all successors, do                     */
+                       remove_header_boundchecks(head, changes);
+
+                       d = c_dTable[head];
+                       while (d != NULL) {
+                               remove_boundchecks(d->value, -1, changes, BOUNDCHECK_REGULAR);
+                               d = d->next;
+                               }
+           
+#ifdef LOOP_DEBUG
+                       printf("Array-bound checks finished\n");                                                        
+                       fflsuh(stdout);
+#endif
+
+                       mark_loop_nodes(lc);
+
+#ifdef LOOP_DEBUG                      
+                       printf("START: create static checks\n");
+                       fflush(stdout);
+#endif
+
+                       create_static_checks(lc);       /* create checks                                                */
+
+#ifdef LOOP_DEBUG
+                       printf("END: create static checks\n");
+                       fflush(stdout);
+#endif
+                       unmark_loop_nodes(lc);
+                       }
+               }
+       /* else
+               printf("No array accesses found\n");                                                                    */
+
+#ifdef STATISTICS
+       c_stat_num_loops++;             /* increase number of loops                                                     */      
+
+       c_stat_sum_accesses += c_stat_array_accesses;
+       c_stat_sum_full += c_stat_full_opt;
+       c_stat_sum_no += c_stat_no_opt;
+       c_stat_sum_lower += c_stat_lower_opt;
+       c_stat_sum_upper += c_stat_upper_opt;
+       c_stat_sum_or += c_stat_or;
+       c_stat_sum_exception += c_stat_exception;
+
+       c_stat_array_accesses = 0;              
+       c_stat_full_opt = 0;
+       c_stat_no_opt = 0;
+       c_stat_lower_opt = 0;
+       c_stat_upper_opt = 0;   
+       c_stat_or = c_stat_exception = 0;
+#endif
+       
+}
+
+/*     This function preforms necessary setup work, before the recursive function
+       optimize_single loop can be called.
+*/
+void optimize_loops()
+{
+       struct LoopContainer *lc = c_allLoops;
+
+       /* first, merge loops with same header node - all loops with the same           */
+       /* header node are optimizied in one pass, because they all depend on the       */
+       /* same dynamic loop condition                                                                                          */
+
+#ifdef LOOP_DEBUG
+       printf("start analyze_double_headers\n");
+       fflush(stdout);
+#endif
+
+       analyze_double_headers();
+
+       /* create array with loop nesting levels - nested loops cause problems,         */
+       /* especially, when they modify index variables used in surrounding     loops   */
+       /* store results in array c_nestedLoops and c_hierarchie                                        */
+
+#ifdef LOOP_DEBUG
+       printf("double done\n");
+       fflush(stdout);
+#endif
+
+       analyze_nested();
+
+#ifdef LOOP_DEBUG
+       printf("analyze nested done\n");
+       fflush(stdout);
+#endif
+
+       /* create array with entries for current loop                                                           */
+       c_current_loop = DMNEW(int, block_count);       
+       c_toVisit = DMNEW(int, block_count);
+       c_var_modified = DMNEW(int, maxlocals);
+       c_null_check = DMNEW(int, maxlocals);
+
+       if ((c_constraints = (struct Constraint **) malloc((maxlocals+1) * sizeof(struct Constraint *))) == NULL)
+               c_mem_error();
+
+#ifdef STATISTICS
+       c_stat_num_loops = 0;           /* set statistic vars to zero                                   */
+       c_stat_array_accesses = c_stat_sum_accesses = 0;                
+       c_stat_full_opt = c_stat_sum_full = 0;
+       c_stat_no_opt = c_stat_sum_no = 0;
+       c_stat_lower_opt = c_stat_sum_lower = 0;
+       c_stat_upper_opt = c_stat_sum_upper = 0;
+       c_stat_or = c_stat_sum_or = 0;
+       c_stat_exception = c_stat_sum_exception = 0;
+#endif
+       /* init vars needed by all loops                                            */
+       c_needs_redirection = false;
+       c_newstart = NULL;
+       c_old_xtablelength = exceptiontablelength;
+
+       /* loops have been topologically sorted                                     */
+       lc = c_allLoops;
+       while (lc != NULL) {
+               optimize_single_loop(lc);
+
+#ifdef LOOP_DEBUG
+               printf(" *** Optimized loop *** \n");
+               fflush(stdout);
+#endif
+
+               lc = lc->next;
+               }
+#ifdef LOOP_DEBUG
+       printf("---*** All loops finished ***---\n");
+       fflush(stdout);
+#endif
+
+       /* if global BB list start is modified, set block to new start              */
+       if (c_needs_redirection == true)
+               block = c_newstart;
+
+}
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
+
+
+
diff --git a/narray/graph.c b/narray/graph.c
new file mode 100644 (file)
index 0000000..c13844a
--- /dev/null
@@ -0,0 +1,401 @@
+/* graph.c *********************************************************************
+
+        Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+        See file COPYRIGHT for information on usage and disclaimer of warranties.
+
+        Contains the functions which build a list, that represents the control
+               flow graph of the procedure, that is being analyzed.
+
+        Authors: Christopher Kruegel      EMAIL: cacao@complang.tuwien.ac.at
+
+        Last Change: 1998/17/02
+
+*******************************************************************************/
+
+void dF(int from, int blockIndex);
+                                                       
+void LoopContainerInit(struct LoopContainer *lc, int i)
+{
+       struct LoopElement *le = DMNEW(struct LoopElement, 1);
+
+       le->next = NULL;
+
+       lc->parent = NULL;
+
+       lc->tree_right = NULL;
+       lc->tree_down = NULL;
+
+       lc->exceptions = NULL;
+
+       lc->in_degree = 0;
+       le->node = lc->loop_head = i;
+       le->block = &block[i];
+
+       /* lc->nodes = (int *) malloc(sizeof(int)*block_count);
+       lc->nodes[0] = i; */
+
+       lc->nodes = le;
+}
+       
+/*     depthFirst() builds the control flow graph out of the intermediate code of  
+       the procedure, that is to be optimized and stores the list in the global 
+       variable c_dTable 
+*/                                                                     
+void depthFirst()
+{
+       int i, j; 
+       struct depthElement *hp;
+
+/*     allocate memory and init gobal variables needed by function dF(int, int)        */
+  
+       if ((c_defnum = (int *) malloc(block_count * sizeof(int))) == NULL)             
+               c_mem_error();
+       if ((c_numPre = (int *) malloc(block_count * sizeof(int))) == NULL)
+               c_mem_error();
+       if ((c_parent = (int *) malloc(block_count * sizeof(int))) == NULL)
+               c_mem_error();
+       if ((c_reverse = (int *) malloc(block_count * sizeof(int))) == NULL)
+               c_mem_error();
+       
+       if ((c_pre = (int **) malloc(block_count * sizeof(int *))) == NULL)
+               c_mem_error(); 
+
+       if ((c_dTable = (struct depthElement **) malloc(block_count * sizeof(struct depthElement *))) == NULL)
+               c_mem_error();
+       
+       for (i = 0; i < block_count; ++i) {
+               c_defnum[i] = c_parent[i] = -1;
+               c_numPre[i] = c_reverse[i] = 0;
+
+               if ((c_pre[i] = (int *) malloc(block_count * sizeof(int))) == NULL)
+                       c_mem_error();
+               c_dTable[i] = NULL;
+           }
+  
+       c_globalCount = 0;
+       c_allLoops = NULL;
+  
+       dF(-1, 0);      /* call helper function dF that traverses basic block structure */
+}
+
+/*     dF starts from the first block of the given procedure and traverses the 
+       control flow graph in a depth-first order, thereby building up the adeacency
+       list c_dTable
+*/ 
+void dF(int from, int blockIndex)
+{
+       instruction *ip;
+       s4 *s4ptr;
+       int high, low, count;
+       struct depthElement *hp;
+       struct LoopContainer *tmp; 
+       int cnt, *ptr;
+       
+       if (from >= 0) {        
+/*     the current basic block has a predecessor (ie. is not the first one)            */
+               if ((hp = (struct depthElement *) malloc(sizeof(struct depthElement))) == NULL)
+                       c_mem_error();                  /* cretae new depth element                                     */
+
+               hp->next = c_dTable[from];      /* insert values                                                        */
+               hp->value = blockIndex;
+               hp->changes = NULL;
+               
+               c_dTable[from] = hp;    /* insert into table                                                    */
+           }
+  
+       if (from == blockIndex) {       /* insert one node loops into loop container    */
+               if ((tmp = (struct LoopContainer *) malloc(sizeof(struct LoopContainer))) == NULL)
+                       c_mem_error();
+               LoopContainerInit(tmp, blockIndex);
+               tmp->next = c_allLoops;
+               c_allLoops = tmp;
+           }
+
+#ifdef C_DEBUG
+       if (blockIndex > block_count) {
+               fprintf(stderr, "DepthFirst: BlockIndex exceeded\n");
+               exit(1);
+               }               
+#endif
+
+       ip = block[blockIndex].iinstr + block[blockIndex].icount -1;
+                                                                               /* set ip to last instruction                   */
+                                                                       
+       if (c_defnum[blockIndex] == -1) {       /* current block has not been visited   */
+           c_defnum[blockIndex] = c_globalCount;       /* update global count                  */
+           c_parent[blockIndex] = from;        /* write parent block of current one    */
+               c_reverse[c_globalCount] = blockIndex;
+               ++c_globalCount;
+               
+               if (!block[blockIndex].icount) {
+                                                                               /* block does not contain instructions  */
+                       dF(blockIndex, blockIndex+1);
+                   }
+               else {                                                  /* for all successors, do                               */
+                       switch (ip->opc) {                      /* check type of last instruction               */
+                       case ICMD_RETURN:
+                       case ICMD_IRETURN:
+                       case ICMD_LRETURN:
+                       case ICMD_FRETURN:
+                       case ICMD_DRETURN:
+                       case ICMD_ARETURN:
+                       case ICMD_ATHROW:
+                               break;                                  /* function returns -> end of graph             */        
+                               
+                       case ICMD_IFEQ:
+                       case ICMD_IFNE:
+                       case ICMD_IFLT:
+                       case ICMD_IFGE:
+                       case ICMD_IFGT:
+                       case ICMD_IFLE:
+                       case ICMD_IFNULL:
+                       case ICMD_IFNONNULL:
+                       case ICMD_IF_ICMPEQ:
+                       case ICMD_IF_ICMPNE:
+                       case ICMD_IF_ICMPLT:
+                       case ICMD_IF_ICMPGE:
+                       case ICMD_IF_ICMPGT:
+                       case ICMD_IF_ICMPLE:
+                       case ICMD_IF_ACMPEQ:
+                       case ICMD_IF_ACMPNE:                            /* branch -> check next block   */
+                          dF(blockIndex, blockIndex + 1);
+                          /* fall throu */
+                          
+                       case ICMD_GOTO:
+                               dF(blockIndex, block_index[ip->op1]);         
+                               break;                                                  /* visit branch (goto) target   */
+                               
+                       case ICMD_TABLESWITCH:                          /* switch statement                             */
+                               s4ptr = ip->val.a;
+                               
+                               dF(blockIndex, block_index[*s4ptr]);    /* default branch               */
+                               
+                               s4ptr++;
+                               low = *s4ptr;
+                               s4ptr++;
+                               high = *s4ptr;
+                               
+                               count = (high-low+1);
+                               
+                               while (--count >= 0) {
+                                       s4ptr++;
+                                       dF(blockIndex, block_index[*s4ptr]);
+                                   }
+                               break;
+                               
+                       case ICMD_LOOKUPSWITCH:                         /* switch statement                             */
+                               s4ptr = ip->val.a;
+                          
+                               dF(blockIndex, block_index[*s4ptr]);    /* default branch               */
+                               
+                               ++s4ptr;
+                               count = *s4ptr++;
+                               
+                               while (--count >= 0) {
+                                       dF(blockIndex, block_index[s4ptr[1]]);
+                                       s4ptr += 2;
+                                   }
+                               break;
+
+                       case ICMD_JSR:
+                               c_last_jump = blockIndex;
+                               dF(blockIndex, block_index[ip->op1]);         
+                               break;
+                               
+                       case ICMD_RET:
+                               dF(blockIndex, c_last_jump+1);
+                               break;
+                               
+                       default:
+                               dF(blockIndex, blockIndex + 1);
+                               break;  
+                           }                         
+                   }
+           } 
+
+       for (ptr = c_pre[blockIndex], cnt = 0; cnt < c_numPre[blockIndex]; ++cnt, ++ptr)
+       {
+               if (*ptr == from)
+                       break;
+       }
+
+       if (cnt >= c_numPre[blockIndex]) {      
+               c_pre[blockIndex][c_numPre[blockIndex]] = from;
+                                                   /* add predeccessors to list c_pre          */
+               c_numPre[blockIndex]++;                         /* increase number of predecessors      */              
+           }
+    
+}
+
+/* a slightly modified version of dF(int, int) that is used to traverse the part 
+   of the control graph that is not reached by normal program flow but by the 
+   raising of exceptions (code of catch blocks)
+*/
+void dF_Exception(int from, int blockIndex)
+{
+       instruction *ip;
+       s4 *s4ptr;
+       int high, low, count;
+       struct depthElement *hp;
+       struct LoopContainer *tmp; 
+
+       if (c_exceptionVisit[blockIndex] < 0)   /* has block been visited, return       */
+               c_exceptionVisit[blockIndex] = 1;
+       else
+               return;
+
+       if (c_dTable[blockIndex] != NULL)               /* back to regular code section         */
+               return;
+
+       if (from >= 0) {                /* build exception graph (in c_exceptionGraph)          */
+           if ((hp = (struct depthElement *) malloc(sizeof(struct depthElement))) == NULL)
+                       c_mem_error();
+
+               hp->next = c_exceptionGraph[from];              
+               hp->value = blockIndex;
+               hp->changes = NULL;
+
+               c_exceptionGraph[from] = hp;
+           }
+       
+#ifdef C_DEBUG
+       if (blockIndex > block_count) {
+               fprintf(stderr, "DepthFirst: BlockIndex exceeded\n");
+               exit(1);
+        }
+#endif
+
+       ip = block[blockIndex].iinstr + block[blockIndex].icount -1;
+       
+       if (!block[blockIndex].icount)
+               dF_Exception(blockIndex, blockIndex+1);
+       else {
+               switch (ip->opc) {
+               case ICMD_RETURN:
+               case ICMD_IRETURN:
+               case ICMD_LRETURN:
+               case ICMD_FRETURN:
+               case ICMD_DRETURN:
+               case ICMD_ARETURN:
+               case ICMD_ATHROW:
+                       break;                                 
+               
+               case ICMD_IFEQ:
+               case ICMD_IFNE:
+               case ICMD_IFLT:
+               case ICMD_IFGE:
+               case ICMD_IFGT:
+               case ICMD_IFLE:
+               case ICMD_IFNULL:
+               case ICMD_IFNONNULL:
+               case ICMD_IF_ICMPEQ:
+               case ICMD_IF_ICMPNE:
+               case ICMD_IF_ICMPLT:
+               case ICMD_IF_ICMPGE:
+               case ICMD_IF_ICMPGT:
+               case ICMD_IF_ICMPLE:
+               case ICMD_IF_ACMPEQ:
+               case ICMD_IF_ACMPNE:
+                       dF_Exception(blockIndex, blockIndex + 1);
+                       /* fall throu */
+         
+               case ICMD_GOTO:
+                       dF_Exception(blockIndex, block_index[ip->op1]);         
+                       break;
+         
+               case ICMD_TABLESWITCH:
+                       s4ptr = ip->val.a;
+                       
+                       /* default branch */
+                       dF_Exception(blockIndex, block_index[*s4ptr]);
+                       
+                       s4ptr++;
+                       low = *s4ptr;
+                       s4ptr++;
+                       high = *s4ptr;
+                       
+                       count = (high-low+1);
+
+                       while (--count >= 0) {
+                               s4ptr++;
+                               dF_Exception(blockIndex, block_index[*s4ptr]);
+                           }
+                       break;
+
+               case ICMD_LOOKUPSWITCH:
+                       s4ptr = ip->val.a;
+                       /* default branch */
+                       dF_Exception(blockIndex, block_index[*s4ptr]);
+                       
+                       ++s4ptr;
+                       count = *s4ptr++;
+
+                       while (--count >= 0) {
+                               dF_Exception(blockIndex, block_index[s4ptr[1]]);
+                               s4ptr += 2;
+                           }  
+                       break;
+
+               case ICMD_JSR:
+                       c_last_jump = blockIndex;
+                       dF_Exception(blockIndex, block_index[ip->op1]);         
+                       break;
+       
+               case ICMD_RET:
+                       dF_Exception(blockIndex, c_last_jump+1);
+                       break;
+                       
+               default:
+                       dF_Exception(blockIndex, blockIndex + 1);
+                       break;  
+                   }                         
+        }
+}
+
+/*     Test function -> will be removed in final release
+*/
+void resultPass1()
+{
+       int i, j;
+       struct depthElement *hp;
+       
+       printf("\n\n****** PASS 1 ******\n\n");
+       printf("Number of Nodes: %d\n\n", c_globalCount);
+       printf("Predecessors:\n");
+       for (i=0; i<block_count; ++i) {
+               printf("Block %d:\t", i);
+               for (j=0; j<c_numPre[i]; ++j)
+                       printf("%d ", c_pre[i][j]);
+               printf("\n");
+       }
+       printf("\n");
+
+       printf("Graph:\n");
+       for (i=0; i<block_count; ++i) {
+               printf("Block %d:\t", i);
+               hp = c_dTable[i];
+               
+               while (hp != NULL) {
+                       printf("%d ", hp->value);
+                       hp = hp->next;
+                   }
+               printf("\n");
+           }
+       printf("\n");
+}
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff --git a/narray/loop.c b/narray/loop.c
new file mode 100644 (file)
index 0000000..7d1a486
--- /dev/null
@@ -0,0 +1,293 @@
+/* loop.c **********************************************************************
+
+        Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+        See file COPYRIGHT for information on usage and disclaimer of warranties.
+
+        Contains the functions which use the control flow graph to do loop detection.
+               The loop detection is performed according to Lengauer-Tarjan algorithm 
+               that uses dominator trees (found eg. in modern compiler implementation
+               by a.w. appel)
+
+        Authors: Christopher Kruegel      EMAIL: cacao@complang.tuwien.ac.at
+
+        Last Change: 1998/17/02
+
+*******************************************************************************/
+
+/*     This function allocates and initializes variables, that are used by the
+        loop detection algorithm
+*/
+void setup()
+{
+       int i;
+
+       c_semi_dom = (int *) malloc(block_count * sizeof(int));
+       c_idom = (int *) malloc(block_count * sizeof(int));
+       c_same_dom = (int *) malloc(block_count * sizeof(int));
+       c_numBucket = (int *) malloc(block_count * sizeof(int));
+       c_ancestor = (int *) malloc(block_count * sizeof(int));
+       c_contains = (int *) malloc(block_count * sizeof(int));
+       c_stack = (int *) malloc(block_count * sizeof(int));
+
+       c_bucket = (int **) malloc(block_count * sizeof(int *));
+  
+       for (i=0; i<block_count; ++i) {
+               c_numBucket[i] = 0;
+               c_stack[i] = c_ancestor[i] = c_semi_dom[i] = c_same_dom[i] = c_idom[i] = -1;
+         
+               c_bucket[i] = (int *) malloc(block_count * sizeof(int));
+               }
+}
+
+/*     This function is a helper function for dominators and has to find the 
+       ancestor of the node v in the control graph, which semi-dominator has the  
+       lowest def-num.
+*/
+int findLowAnc(int v)
+{
+       int u = v;                      /* u is the node which has the current lowest semi-dom  */
+  
+       while (c_ancestor[v] != -1) {   /* as long as v has an ancestor, continue       */
+               if (c_defnum[c_semi_dom[v]] < c_defnum[c_semi_dom[u]])  
+                                                                       /* if v's semi-dom is smaller                           */
+                       u = v;                                  /* it gets the new current node u                       */
+               v = c_ancestor[v];                      /* climb one step up in the tree                        */
+               }
+       return u;                       /* return node with the lowest semi-dominator def-num   */
+}
+
+
+/*     This function builds the dominator tree out of a given control flow graph and 
+       stores its results in c_idom[]. It first calculates the number of possible
+       dominators in c_bucket and eventually determines the single dominator in a 
+       final pass.
+*/
+void dominators()
+{
+       int i, j, semi, s, n, v, actual, p, y;
+  
+       for (n=(c_globalCount-1); n>0; --n) {   /* for all nodes (except last), do      */
+               actual = c_reverse[n];
+               semi = p = c_parent[actual];            
+       
+               /* for all predecessors of current node, do                                                             */
+               for (i=0; i<c_numPre[actual]; ++i) {
+                       v = c_pre[actual][i];
+      
+                       if (c_defnum[v] <= c_defnum[actual])
+                               s = v;                  /* if predecessor has lower def-num     than node       */
+                                                               /* it becomes candidate for semi dominator              */
+                       else
+                               s = c_semi_dom[findLowAnc(v)];
+                                                               /* else the semi-dominator of it's ancestor             */
+                                                               /* with lowest def-num becomes candidate                */
+                       
+                       if (c_defnum[s] < c_defnum[semi])
+                               semi = s;               /* if the def-num of the new candidate is lower */
+                                                               /* than old one, it gets new semi dominator             */
+                       }
+    
+               /* write semi dominator -> according to SEMIDOMINATOR THEOREM                   */
+               c_semi_dom[actual] = semi;                              
+               c_ancestor[actual] = p;                                 
+    
+               c_bucket[semi][c_numBucket[semi]] = actual;
+               c_numBucket[semi]++;    /* defer calculation of dominator to final pass */
+      
+
+               /* first clause of DOMINATOR THEOREM, try to find dominator now                 */
+               for (j=0; j<c_numBucket[p]; ++j) {
+                       v = c_bucket[p][j];
+                       y = findLowAnc(v);
+      
+                       if (c_semi_dom[y] == c_semi_dom[v])     
+                               c_idom[v] = p;                  /* if y's dominator is already known    */
+                                                                               /* found it and write to c_idom                 */
+                       else
+                               c_same_dom[v] = y;              /* wait till final pass                                 */
+                       }
+               
+               c_numBucket[p] = 0;
+               }
+  
+       /* final pass to get missing dominators ->second clause of DOMINATOR THEORM     */
+       for (j=1; j<(c_globalCount-1); ++j) {           
+               if (c_same_dom[c_reverse[j]] != -1)     
+                       c_idom[c_reverse[j]] = c_idom[c_same_dom[c_reverse[j]]];
+               }
+}
+
+/*     A helper function needed by detectLoops() that checks, whether a given 
+       connection between two nodes in the control flow graph is possibly part
+       of a loop (is a backEdge).
+*/
+int isBackEdge(int from, int to)
+{
+       int tmp = c_idom[to];   /* speed optimization: if the to-node is dominated      */
+       while (tmp != -1) {             /* by the from node as it is most of the time,          */
+               if (tmp == from)        /* there is no backEdge                                                         */
+                       return 0;
+               tmp = c_idom[tmp];
+               }
+
+       tmp = c_idom[from];             /* if from-node doesn't dominate to-node, we have       */
+       while (tmp != -1) {             /* to climb all the way up from the from-node to        */
+               if (tmp == to)          /* the top to check, whether it is dominated by to      */
+                       return 1;               /* if so, return a backedge                                                     */
+               tmp = c_idom[tmp];
+               }
+
+       return 0;                               /* else, there is no backedge                                           */
+}
+
+
+/*     These stack functions are helper functions for createLoop(int, int)  
+       to manage the set of nodes in the current loop.
+*/
+void push(int i, struct LoopContainer *lc)
+{
+       struct LoopElement *le = lc->nodes, *t;
+
+       if (!c_contains[i])
+       {
+               t = DMNEW(struct LoopElement, 1);
+               
+               t->node = i;
+               t->block = &block[i];
+
+               c_contains[i] = 1;
+
+               if (i < le->node)
+               {
+                       t->next = lc->nodes;
+                       lc->nodes = t;
+               }
+               else
+               {
+                       while ((le->next != NULL) && (le->next->node < i))
+                               le = le->next;
+
+                       t->next = le->next;
+                       le->next = t;
+               }
+
+               c_stack[c_stackPointer++] = i;
+       }
+}
+int pop()
+{
+       return (c_stack[--c_stackPointer]);
+}
+int isFull()
+{
+       return (c_stackPointer);
+}
+
+
+/*     This function is a helper function, that finds all nodes, that belong to 
+       the loop with a known header node and a member node of the loop (and a 
+       back edge between these two nodes).
+*/
+void createLoop(int header, int member)
+{
+       int i, nextMember;
+
+       struct LoopContainer *currentLoop = (struct LoopContainer *) malloc(sizeof(struct LoopContainer));
+       LoopContainerInit(currentLoop, header);         /* set up loop structure                */
+       
+       for (i=0; i<block_count; ++i)
+               c_contains[i] = 0;
+       c_contains[header] = 1;
+
+       c_stackPointer = 0;                             /* init stack with first node of the loop       */
+       push(member, currentLoop);
+
+       while (isFull()) {                              /* while there are still unvisited nodes        */
+               nextMember = pop();
+               
+               /* push all predecessors, while they are not equal to loop header               */
+               for (i=0; i<c_numPre[nextMember]; ++i)                  
+                       push(c_pre[nextMember][i], currentLoop);                
+               }
+
+       currentLoop->next = c_allLoops;
+       c_allLoops = currentLoop;
+}
+
+
+/*     After all dominators have been calculated, the loops can be detected and
+        added to the global list c_allLoops.
+*/
+void detectLoops()
+{
+       int i;
+       struct depthElement *h;
+       
+       /* for all edges in the control flow graph do                                                           */
+       for (i=0; i<block_count; ++i) {                 
+               h = c_dTable[i];
+
+               while (h != NULL) {
+                       /* if it's a backedge, than add a new loop to list                                      */
+                       if (isBackEdge(i, h->value))     
+                               createLoop(h->value, i);
+                       h = h->next;
+                       }
+               }
+}
+
+/*     This function is called by higher level routines to perform the loop 
+       detection and set up the c_allLoops list.
+*/
+void analyseGraph()
+{
+  setup();
+  dominators();
+  detectLoops();
+}
+
+/*     Test function -> will be removed in final release
+*/
+void resultPass2()
+{
+  int i, j;
+  struct LoopContainer *lc = c_allLoops;
+  struct LoopElement *le;
+  
+  printf("\n\n****** PASS 2 ******\n\n");
+  
+  printf("Loops:\n\n");
+  
+  j=0;
+  while (lc != NULL) {
+         printf("Loop [%d]: ", ++j);
+
+         le = lc->nodes;
+         while (le != NULL) {
+           printf("%d ", le->node);
+               printf("\n");
+               le = le->next;
+         }
+
+         lc = lc->next;
+  }
+
+  printf("\n");
+
+}
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
+
+
+
diff --git a/narray/loop.h b/narray/loop.h
new file mode 100644 (file)
index 0000000..962e634
--- /dev/null
@@ -0,0 +1,343 @@
+/* loop.h **********************************************************************
+
+        Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+        See file COPYRIGHT for information on usage and disclaimer of warranties.
+
+               Main header file for array bound removal files
+        
+        Authors: Christopher Kruegel      EMAIL: cacao@complang.tuwien.ac.at
+
+        Last Change: 1998/17/02
+
+*******************************************************************************/
+
+#ifndef __C_ARRAYBOUND_
+#define __C_ARRAYBOUND_
+
+/* #define LOOP_DEBUG */
+
+/*     GLOBAL DEFINES                                                                                                                          */
+
+
+/*     Different types for struct Trace                                                                                        */
+#define TRACE_UNKNOWN 0                        /* unknown                                                                              */
+#define TRACE_ICONST  1                        /* integer constant value                                               */
+#define TRACE_ALENGTH 2                        /* array length value                                                   */
+#define TRACE_IVAR    3                        /* integer variable reference                                   */
+#define TRACE_AVAR    4                        /* object (array) reference                                             */
+
+/*     The ways a variable can be used in a loop                                                                       */
+#define ARRAY_INDEX      0                     /* var used as array index                                              */
+#define VAR_MOD                  1                     /* var changes its value                                                */
+
+/*     The way, integer variables change their values                                                          */
+#define D_UP             0                     /* var is only increased                                                */
+#define D_DOWN           1                     /* var is only decreased                                                */
+#define D_UNKNOWN        2                     /* not known                                                                    */
+
+/*     The different types of operators in loop conditions                                                     */
+#define OP_EQ            0                     /* operator:    ==                                                              */
+#define OP_LT         1                        /* operator:    <                                                               */
+#define OP_GE        2                 /* operator:    >=                                                              */
+#define OP_UNKNOWN       3                     /* operator:    unknown                                                 */
+
+/*     Possible types of static tests (constraints) in struct Constraint                       */
+#define TEST_ZERO                      0       /* check variable against const. lower bound    */
+#define TEST_ALENGTH           1       /* check variable against array length                  */
+#define TEST_CONST_ZERO                2       /* check constant against const. lower bound    */
+#define TEST_CONST_ALENGTH     3       /* check variable against array length                  */
+#define TEST_UNMOD_ZERO                4       /* check var. that is constant in loop against  */
+                                                               /* constant lower bound                                                 */
+#define TEST_UNMOD_ALENGTH     5       /* check var. that is constant in loop against  */
+                                                               /* array length                                                                 */
+#define TEST_RS_ZERO           6       /* check constant part of loop condition against*/
+                                                               /* constant lower bound                                                 */
+#define TEST_RS_ALENGTH                7       /* check constant part of loop condition against*/
+                                                               /* array length                                                                 */
+
+/*     Possible types of bound check optimizations                                                                     */
+#define OPT_UNCHECKED  0               /* access not checked yet - first visit                 */
+#define OPT_NONE               1               /* no optimization                                                              */
+#define OPT_FULL               2               /* fully remove bound check                                             */
+#define OPT_LOWER              3               /* remove check againt zero                                             */
+#define OPT_UPPER              4               /* remove check against array length                    */
+
+/*     The different ways, remove_boundcheck(.) can be called                                          */ 
+#define BOUNDCHECK_REGULAR     0       /* perform regular optimization                                 */
+#define BOUNDCHECK_SPECIAL     1       /* only optimize header node - and ignore               */
+                                                               /* information from loop condition                              */
+
+#define LOOP_PART       0x1     /* a flag that marks a BB part of a loop        */
+#define HANDLER_PART    0x2     /* a flag that marks a BB part of ex-handler    */
+#define HANDLER_VISITED 0x4     /* flag to prevent loop if copying catch blocks */
+
+/*     STRUCT DEFINITIONS                                                                                                                      */
+
+/*     This struct records information about interesting vars (vars that are modified
+       or used as an array index in loops.
+*/
+struct LoopVar
+{
+       int value;                                      /* reference to array of local variables                */
+
+       int modified;                           /* set if value of var is changed                               */
+       int index;                                      /* set if var is used as array index                    */
+
+       int static_l;                           /* var is never decremented -> static lower             */
+                                                               /* bound possible                                                               */
+       int static_u;                           /* var is never incremented -> static upper             */
+                                                               /* bound possible                                                               */
+       int dynamic_l;
+       int dynamic_l_v;                        /* variable is left side of loop condition in   */
+                                                               /* variable + dynamic_l >= right side                   */
+       int dynamic_u;
+       int dynamic_u_v;                        /* variable is left side of loop condition in   */
+                                                               /* variable + dynamic_u < right side                    */
+       struct LoopVar *next;           /* list pointer                                                                 */
+};
+
+/*     This struct records the needed static test of variables before loop entry.      */
+struct Constraint
+{
+       int type;                                       /* type of test to perform                                              */
+
+       int arrayRef;                           /* array reference involved in test (if any)    */
+       int varRef;                                     /* which variable to test (if involved)                 */
+       int constant;                           /* which constant to test (if involved)                 */
+
+       struct Constraint *next;        /* list pointer                                                                 */
+};
+
+/* This structure is used to record variables that change their value in loops.        */
+struct Changes
+{
+       int var;                                        /* variable involved                                                    */
+       int lower_bound;                        /* a minimum lower bound that is guaranteed             */
+       int upper_bound;                        /* a maximum upper bound that is guaranteed             */
+                                                               /* IMPORTANT: if lower_bound > upper_bound              */
+                                                               /* there are no guarantees at all                               */
+};
+
+/*     This struct is used to build the control flow graph and stores the variable     
+       changes at the beginning of each basic block.
+*/
+struct depthElement
+{
+       int value;                                      /* number of successor of this block                    */
+       struct depthElement *next;      /* list pointer                                                                 */
+       struct Changes **changes;       /* pointer to array of variable changes                 */
+};
+
+/*     Used to build a list of all basicblock, the loop consists of                            
+*/
+struct LoopElement
+{
+       int node;
+       basicblock      *block;                 
+       struct LoopElement *next;
+};
+
+/*     This structure stores informations about a single loop
+*/
+struct LoopContainer
+{
+       int toOpt;                                                      /* does this loop need optimization             */
+               
+       struct LoopElement *nodes;          /* list of BBs this loop consists of    */
+       int loop_head;                      
+       int in_degree;                      /* needed to topological sort loops to  */
+                                           /* get the order of optimizing them     */
+       
+       struct LoopContainer *next;                     /* list pointer                                                 */
+       struct LoopContainer *parent;           /* points to parent loop, if this BB    */
+                                                                               /* is head of a loop                                    */
+
+       struct LoopContainer *tree_right;   /* used for tree hierarchie of loops    */
+       struct LoopContainer *tree_down;
+
+       xtable *exceptions;                 /* list of exception in that loop       */
+};
+
+/*     This struct is needed to record the source of operands of intermediate code
+       instructions. The instructions are scanned backwards and the stack is 
+       analyzed in order to determine the type of operand.
+*/
+struct Trace
+{
+       int type;                                       /* the type of the operand                                              */
+
+       int neg;                                        /* set if negated                                                               */
+       int var;                                        /* variable reference   for IVAR                                */
+                                                               /* array reference              for AVAR/ARRAY                  */
+       int nr;                                         /* instruction number in the basic block, where */
+                                                               /* the trace is defined                                                 */
+       int constant;                           /* constant value               for ICONST                              */
+                                                               /* modifiers                    for IVAR                                */
+};
+
+
+
+/* FUNCTIONS                                                                                                                                   */
+
+void c_mem_error()
+{
+  printf("C_ERROR: Not enough memeory\n");
+  exit(-1);
+} 
+
+/* GLOBAL VARS                                                                                                                                 */
+
+int c_debug_nr;                 /* a counter to number all BB with an unique    */
+                                /* value                                        */
+
+/* modified by graph.c                                                                                                                 */
+
+int *c_defnum;                                 /* array that stores a number for each node     when*/
+                                                               /* control flow graph is traveres depth first   */
+int *c_parent;                                 /* for each node that array stores its parent   */
+int *c_reverse;                                        /* for each def number that array stores the    */
+                                                               /* corresponding node                                                   */
+int c_globalCount;                             /* counter for def numbering                                    */
+int *c_numPre;                                 /* array that stores for each node its number   */
+                                                               /* predecessors                                                                 */
+int **c_pre;                                   /* array of array that stores predecessors              */
+int c_last_jump;                               /* stores the source node of the last jsr instr */
+basicblock *c_last_target;      /* stores the source BB of the last jsr instr  */
+
+struct depthElement **c_dTable;        /* adjacency list for control flow graph                */
+struct depthElement **c_exceptionGraph;        /* adjacency list for exception graph   */
+
+struct LoopContainer *c_allLoops;              /* list of all loops                                    */
+struct LoopContainer *c_loop_root;             /* root of loop hierarchie tree                 */
+
+int *c_exceptionVisit;                 /* array that stores a flag for each node part  */
+                                                               /* of the exception graph                                               */
+
+/* modified by loop.c                                                                                                                  */
+
+int *c_semi_dom;                               /* store for each node its semi dominator               */
+int *c_idom;                                   /* store for each node its dominator                    */
+int *c_same_dom;                               /* temp array to hold nodes with same dominator */
+int *c_ancestor;                               /* store for each node its ancestor with lowest */
+                                                               /* semi dominator                                                               */
+int *c_numBucket;                              
+int **c_bucket;
+
+int *c_contains;                               /* store for each node whether it's part of loop*/
+int *c_stack;                                  /* a simple stack as array                                              */
+int c_stackPointer;                            /* stackpointer                                                                 */
+
+
+/* modified by analyze.c                                                                                                               */
+
+struct LoopContainer *root;     /* the root pointer for the hierarchie tree of  */
+                                /* all loops in that procedure                  */
+
+int c_needed_instr;                            /* number of instructions that have to be               */
+                                                               /* inserted before loop header to make sure             */
+                                                               /* array optimization is legal                                  */
+int c_rs_needed_instr;                 /* number of instructions needed to load the    */
+                                                               /* value ofthe right side of the loop condition */
+int *c_nestedLoops;                            /* store for each node the header node of the   */
+                                                               /* loop this node belongs to, -1 for none               */
+int *c_hierarchie;              /* store a loop hierarchie                      */
+int *c_toVisit;                                        /* set for each node that is part of the loop   */
+
+int *c_current_loop;                   /* for each node:
+                                                               /* store 0:     node is not part of loop                        */
+                                                               /* store 1:     node is loop header                                     */
+                                                               /* store 2:     node is in loop but not part of any     */
+                                                               /*                      nested loop
+                                                               /* store 3:     node is part of nested loop                     */
+
+int c_current_head;                            /* store number of node that is header of loop  */
+int *c_var_modified;                   /* store for each local variable whether its    */
+                                                               /* value is changed in the loop                                 */
+
+struct Trace *c_rightside;             /* right side of loop condition                                 */
+struct Constraint **c_constraints;
+                                                               /* array that stores for each variable a list   */
+                                                               /* static tests (constraints) that have to be   */
+                                                               /* performed before loop entry                                  */
+                                                               /* IMPORTANT: c_constraints[maxlocals] stores   */
+                                                               /*                        the tests for constants and the       */
+                                                               /*                        right side of loop condition          */
+       
+struct LoopVar *c_loopvars;            /* a list of all intersting variables of the    */
+                                                               /* current loop (variables that are modified or */
+                                                               /* used as array index                                                  */
+
+basicblock *c_first_block_copied; /* pointer to the first block, that is copied */
+                                  /* during loop duplication                    */
+
+basicblock *c_last_block_copied;  /* last block, that is copied during loop     */
+                                  /* duplication                                */
+
+int *c_null_check;              /* array to store for local vars, whether they  */
+                                /* need to be checked against the null reference*/
+                                /* in the loop head                             */
+
+bool c_needs_redirection;       /* if a loop header is inserted as first block  */
+                                /* into the global BB list, this is set to true */
+                                 
+basicblock *c_newstart;         /* if a loop header is inserted as first block  */
+                                /* into the gloal BB list, this pointer is the  */
+                                /* new start                                    */
+int c_old_xtablelength;         /* used to store the original tablelength       */
+
+/* set debug mode                                                                                                                              */
+#define C_DEBUG
+
+
+/* declare statistic variables                                                                                                 */
+#ifdef STATISTICS
+
+int c_stat_num_loops;                  /* number of loops                                                              */
+
+/* statistics per loop                                                                                                                 */
+int c_stat_array_accesses;             /* number of array accesses                                             */
+
+int c_stat_full_opt;                   /* number of fully optimized accesses                   */
+int c_stat_no_opt;                             /* number of not optimized accesses                             */
+int c_stat_lower_opt;                  /* number of accesses where check against zero  */
+                                                               /* is removed                                                                   */
+int c_stat_upper_opt;                  /* number of accesses where check against array */
+                                                               /* lengh is removed                                                             */
+int c_stat_or;                                 /* set if optimization is cancelled because of  */
+                                                               /* or in loop condition                                                 */
+int c_stat_exception;                  /* set if optimization is cancelled because of  */
+                                                               /* index var modified in catch block                    */
+
+/* statistics per procedure                                                                                                            */
+int c_stat_sum_accesses;               /* number of array accesses                                             */
+
+int c_stat_sum_full;                   /* number of fully optimized accesses                   */
+int c_stat_sum_no;                             /* number of not optimized accesses                             */
+int c_stat_sum_lower;                  /* number of accesses where check against zero  */
+                                                               /* is removed                                                                   */
+int c_stat_sum_upper;                  /* number of accesses where check against array */
+                                                               /* lengh is removed                                                             */
+int c_stat_sum_or;                             /* set if optimization is cancelled because of  */
+                                                               /* or in loop condition                                                 */
+int c_stat_sum_exception;              /* set if optimization is cancelled because of  */
+
+
+#endif
+
+#endif
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
+
diff --git a/narray/tracing.c b/narray/tracing.c
new file mode 100644 (file)
index 0000000..e963346
--- /dev/null
@@ -0,0 +1,647 @@
+/* tracing.c *******************************************************************
+
+        Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
+
+        See file COPYRIGHT for information on usage and disclaimer of warranties.
+
+        Contains the functions which create a trace. A trace is a structure, that
+               contains the source of the arguments of a given instruction. For more
+               details see function tracing(basicblock, int, int) below.
+
+        Authors: Christopher Kruegel      EMAIL: cacao@complang.tuwien.ac.at
+
+        Last Change: 1998/17/02
+
+*******************************************************************************/
+
+/*     Test function -> will be removed in final release
+*/
+void printTraceResult(struct Trace *p)
+{
+       printf("TRACE: ");
+
+       switch (p->type) {
+       case TRACE_UNKNOWN:
+               printf("\tUnknown");
+               break;
+       case TRACE_ICONST:
+               printf("\tconst - %d", p->constant);
+               break;
+       case TRACE_ALENGTH:
+               printf("\tarray - (%d)%d - %d", p->neg, p->var, p->constant);
+               break;
+       case TRACE_IVAR:
+               printf("\tivar - (%d)%d - %d", p->neg, p->var, p->constant);
+               break;
+       case TRACE_AVAR:
+               printf("\tavar - %d", p->var);
+               break;
+               }
+       
+       printf("\n");
+}
+
+    
+/*     A function that creates a new trace structure and initializes its values
+*/
+struct Trace* create_trace(int type, int var, int constant, int nr)
+{
+       struct Trace *t;
+       if ((t = (struct Trace *) malloc(sizeof(struct Trace))) == NULL)
+               c_mem_error();
+
+       t->type = type;
+
+       t->neg = 1;
+       t->var = var;
+       t->nr = nr;
+
+       t->constant = constant;
+
+       return t;
+}
+
+/*     When the function tracing(...) encounters an add instruction during its 
+       backward scan over the instructions, it trys to identify the source of the
+       arguments of this add function. The following function performs this task.
+*/
+struct Trace* add(struct Trace* a, struct Trace* b)
+{
+       switch (a->type) {                      /* check the first argument of add. when it             */
+       case TRACE_UNKNOWN:                     /* is unknown or array-address, return unknown  */
+       case TRACE_AVAR:
+               return create_trace(TRACE_UNKNOWN, -1, 0, 0);
+
+       case TRACE_ICONST:                      /* when it is constant, check second argument   */
+               switch (b->type) {
+               case TRACE_IVAR:                        /* when second argument is a variable value */
+               case TRACE_ALENGTH:                     /* or array length, just add the constant       */
+                       a->type = b->type;
+                       a->var  = b->var;
+                       a->neg  = b->neg;
+                       a->constant += b->constant;
+                       break;
+               case TRACE_UNKNOWN:                     /* when unknown/array ref. return unknown       */
+               case TRACE_AVAR:
+                     return create_trace(TRACE_UNKNOWN, -1, 0, 0);
+           case TRACE_ICONST:                  /* when both are constant, just add them        */
+                       a->constant += b->constant;
+                       break;
+                       }
+               break;
+
+       case TRACE_IVAR:                        /* when it is a variable value or array length, */
+       case TRACE_ALENGTH:                     /* check second argument                                                */
+               switch (b->type) {
+               case TRACE_IVAR:                        /* when it is not a constant return unknown     */
+               case TRACE_ALENGTH:
+               case TRACE_UNKNOWN:
+               case TRACE_AVAR:
+                       return create_trace(TRACE_UNKNOWN, -1, 0, 0);
+               case TRACE_ICONST:                      /* when it is a constant, just add it           */
+                       a->constant += b->constant;
+                       break;
+                       }
+               break;
+               }
+
+       return a;
+}
+
+/*     When the function tracing(...) encounters a neg instruction during its 
+       backward scan over the instructions, it trys to identify the source of the
+       argument of this neg function. The following function performs this task.
+*/
+struct Trace* negate(struct Trace* a)
+{
+       switch (a->type) {                              /* check argument type                                          */
+       case TRACE_IVAR:                                /* when it is variable/array length value       */
+       case TRACE_ALENGTH:                                     
+               a->neg = -(a->neg);                             /* invert negate flag                                   */
+               a->constant = -(a->constant);   /* and negate constant                                  */
+               break;
+       
+       case TRACE_ICONST:                              /* when it is a constant, negate it                     */
+               a->constant = -(a->constant);
+               break;
+
+       default:
+               a->type = TRACE_UNKNOWN;        /* else return unknown                                          */
+               break;
+               }
+
+  return a;
+}
+
+/*     When the function tracing(...) encounters a sub instruction during its backward
+       scan over the instructions, it trys to identify the source of the arguments of
+       this sub function. The following function performs this task, by applaying the
+       negate function on the second argument and then adds the values.
+*/
+struct Trace* sub(struct Trace* a, struct Trace* b)
+{
+       struct Trace *c = negate(b);
+       return add(a, c);
+}
+
+
+/*     When the function tracing(...) encounters an array length instruction during
+       its backward scan over the instructions, it trys to identify the source of 
+       the argument ofthis array length function. The following function performs 
+       this task.
+*/
+struct Trace* array_length(struct Trace* a)
+{
+       if (a->type == TRACE_AVAR)      /* if argument is an array ref., mark the type  */
+               a->type = TRACE_ALENGTH;        /* as array length of this array reference      */
+       else
+               a->type = TRACE_UNKNOWN;        /* else it's unknown                                    */
+
+       return a;
+}
+
+/*     This function is used to identify the types of operands of an intermediate 
+       code instruction.It is needed by functions, that analyze array accesses. If 
+       something is stored into or loaded from an array, we have to find out, which 
+       array really has been accessed. When a compare instruction is encountered at
+       a loop header, the type of its operands have to be detected to construct
+       dynamic bounds for some variables in the loop. This function returns a struct
+       Trace (see loop.h for more details about this structure). block is the basic
+       block to be examined, index holds the offset of the examined instruction in
+       this block. The arguments are retrieved by using the stack structure, the 
+       compilation process sets up. During the backwards scan of the code, it is 
+       possible, that other instructions temporaray put or get values from the stack
+       and hide the value, we are interested in below them. The value temp counts
+       the number of values on the stack, the are located beyond the target value.
+*/
+struct Trace* tracing(basicblock *block, int index, int temp)
+{
+       int args, retval;
+       instruction *ip;
+       methodinfo *m;
+
+       if (index >= 0) {
+               ip = block->iinstr+index;
+
+/*     printf("TRACING with %d %d %d\n", index, temp, ip->opc);
+*/
+               switch (ip->opc) {
+               
+               /* nop, nullcheckpop                                                                                                    */
+               case ICMD_NOP:                          /* ...  ==> ...                                                         */
+                       return tracing(block, index-1, temp);
+                       break;
+      
+               case ICMD_NULLCHECKPOP:         /* ..., objectref  ==> ...                                      */
+                       return tracing(block, index-1, temp+1);
+                       break;
+
+               /* Constants                                                                                                                    */
+               case ICMD_LCONST:                               
+               case ICMD_DCONST:
+               case ICMD_FCONST:
+               case ICMD_ACONST:
+                       if (temp > 0)                           
+                               return tracing(block, index-1, temp-1);         
+                       else
+                               return create_trace(TRACE_UNKNOWN, -1, 0, index);
+                       break;                                          
+
+               case ICMD_ICONST:
+                       if (temp > 0)           /* if the target argument is not on top                 */
+                               return tracing(block, index-1, temp-1); /* look further                 */
+                       else
+                               return create_trace(TRACE_ICONST, -1, ip->val.i, index);
+                       break;                          /* else, return the value, found at this instr. */
+
+               /* Load/Store                                                                                                                   */
+        case ICMD_LLOAD:               
+               case ICMD_DLOAD:    
+               case ICMD_FLOAD:
+                       if (temp > 0)
+                               return tracing(block, index-1, temp-1);
+                       else
+                               return create_trace(TRACE_UNKNOWN, -1, 0, index);
+                       break;
+    
+               case ICMD_ILOAD:
+                       if (temp > 0)
+                               return tracing(block, index-1, temp-1);
+                   else
+                               return create_trace(TRACE_IVAR, ip->op1, 0, index);
+                       break;
+
+               case ICMD_ALOAD:    
+                       if (temp > 0)
+                               return tracing(block, index-1, temp-1);
+                       else
+                               return create_trace(TRACE_AVAR, ip->op1, 0, index);                     
+                       break;
+               
+               case ICMD_LSTORE:    
+               case ICMD_DSTORE:    
+               case ICMD_FSTORE:
+               case ICMD_ISTORE:
+               case ICMD_ASTORE:    
+                       return tracing(block, index-1, temp+1);
+                       break;
+       
+
+               /* pop/dup/swap                                                                                                                 */
+               case ICMD_POP:      
+                       return tracing(block, index-1, temp+1);
+                       break;
+     
+               case ICMD_POP2:  
+                       return tracing(block, index-1, temp+2);
+                       break;
+
+               case ICMD_DUP:
+                       if (temp > 0)
+                               return tracing(block, index-1, temp-1);
+                       else
+                               return tracing(block, index-1, temp);
+                       break;
+
+               case ICMD_DUP_X1:                       /* ..., a, b ==> ..., b, a, b                           */
+                       switch (temp) {
+                       case 0:                                 /* when looking for top or third element,       */
+                       case 2:                                 /* just return top element                                      */
+                               return tracing(block, index-1, 0);
+                       case 1:
+                               return tracing(block, index-1, 1);
+                       default:
+                               return tracing(block, index-1, temp-1);
+                               }
+                       break;
+
+               case ICMD_DUP2:                         /* ..., a, b ==> ..., a, b, a, b                        */
+                       switch (temp) { 
+                       case 0:                                 /* when looking for top or third element        */
+                       case 2:                                 /* just return top element                                      */
+                               return tracing(block, index-1, 0);
+                       case 1:                                 /* when looking for second or fourth element*/
+                       case 3:                                 /* just return second element                           */
+                               return tracing(block, index-1, 1);
+                       default:
+                               return tracing(block, index-1, temp-2);
+                               }
+                       break;
+
+               case ICMD_DUP2_X1:                      /* ..., a, b, c ==> ..., b, c, a, b, c          */
+                       switch (temp) {
+                       case 0:
+                       case 3:
+                               return tracing(block, index-1, 0);
+                       case 1:
+                       case 4:
+                               return tracing(block, index-1, 1);
+                       case 2:
+                               return tracing(block, index-1, 2);
+                       default:
+                               return tracing(block, index-1, temp-2);
+                               }
+                       break;
+
+               case ICMD_DUP_X2:                       /* ..., a, b, c ==> ..., c, a, b, c                     */
+                       switch (temp) {    
+                       case 0:
+                       case 3:
+                               return tracing(block, index-1, 0);
+                       case 1:
+                       case 4:
+                               return tracing(block, index-1, 1);
+                       case 2:
+                               return tracing(block, index-1, 2);
+                       default:
+                               return tracing(block, index-1, temp-2);
+                               }
+                       break;
+
+               case ICMD_DUP2_X2:                      /* .., a, b, c, d ==> ..., c, d, a, b, c, d     */
+                       switch (temp) {
+                       case 0:
+                       case 4:
+                               return tracing(block, index-1, 0);
+                       case 1:
+                       case 5:
+                               return tracing(block, index-1, 1);
+                       case 2:
+                               return tracing(block, index-1, 2);
+                       case 3:
+                               return tracing(block, index-1, 3);
+                       default:
+                               return tracing(block, index-1, temp-2);
+                               }
+                       break;
+
+               case ICMD_SWAP:                         /* ..., a, b ==> ..., b, a                                      */
+                       switch (temp) {
+                       case 0:
+                               return tracing(block, index-1, 1);
+                       case 1:
+                               return tracing(block, index-1, 0);
+                       default:
+                               return tracing(block, index-1, temp);
+                               }
+                       break;
+      
+               /* Interger operations                                                                                                  */
+           case ICMD_INEG:                             /* ..., value  ==> ..., - value                         */
+                       if (temp > 0)
+                               return tracing(block, index-1, temp);
+                       else                                    /* if an inter neg. operation is found,         */
+                                                                       /* invokethe negate function                            */
+                               return negate(tracing(block, index-1, temp));
+                       break;
+
+               case ICMD_LNEG:                         /* ..., value  ==> ..., - value                         */
+               case ICMD_I2L:                          /* ..., value  ==> ..., value                           */
+               case ICMD_L2I:                          /* ..., value  ==> ..., value                           */
+               case ICMD_INT2BYTE:                     /* ..., value  ==> ..., value                           */
+               case ICMD_INT2CHAR:                     /* ..., value  ==> ..., value                           */
+               case ICMD_INT2SHORT:            /* ..., value  ==> ..., value                           */
+                       if (temp > 0)
+                               return tracing(block, index-1, temp);
+                       else
+                               return create_trace(TRACE_UNKNOWN, -1, 0, index);
+                       break;
+
+               case ICMD_IADD:                         /* ..., val1, val2  ==> ..., val1 + val2        */
+                       if (temp > 0)
+                               return tracing(block, index-1, temp+1);
+                       else                                    /* when add is encountered, invoke add func     */
+                               return add(tracing(block, index-1, 0), tracing(block, index-1, 1));
+                       break;
+
+               case ICMD_IADDCONST:            /* ..., value  ==> ..., value + constant        */
+                       if (temp > 0)
+                               return tracing(block, index-1, temp);
+                       else                                    /* when a constant is added, create a           */
+                                                                       /* constant-trace and use add function          */
+                               return add(tracing(block, index-1, 0), create_trace(TRACE_ICONST, -1, ip->val.i, index));
+                       break;
+
+               case ICMD_ISUB:                         /* ..., val1, val2  ==> ..., val1 - val2        */
+                       if (temp > 0)
+                               return tracing(block, index-1, temp+1);
+                       else                                    /* use sub function for sub instructions        */
+                               return sub(tracing(block, index-1, 1), tracing(block, index-1, 0));
+                       break;
+
+               case ICMD_ISUBCONST:            /* ..., value  ==> ..., value + constant        */
+                       if (temp > 0)
+                               return tracing(block, index-1, temp);
+                       else
+                               return sub(tracing(block, index-1, 0), create_trace(TRACE_ICONST, -1, ip->val.i, index));
+                       break;
+
+               case ICMD_LADD:                         /* ..., val1, val2  ==> ..., val1 + val2        */
+               case ICMD_LSUB:                         /* ..., val1, val2  ==> ..., val1 - val2        */
+               case ICMD_IMUL:                         /* ..., val1, val2  ==> ..., val1 * val2        */
+               case ICMD_LMUL:                         /* ..., val1, val2  ==> ..., val1 * val2        */
+               case ICMD_ISHL:                         /* ..., val1, val2  ==> ..., val1 << val2       */
+               case ICMD_ISHR:                         /* ..., val1, val2  ==> ..., val1 >> val2       */
+               case ICMD_IUSHR:                        /* ..., val1, val2  ==> ..., val1 >>> val2      */
+               case ICMD_LSHL:                         /* ..., val1, val2  ==> ..., val1 << val2       */
+               case ICMD_LSHR:                         /* ..., val1, val2  ==> ..., val1 >> val2       */
+               case ICMD_LUSHR:                        /* ..., val1, val2  ==> ..., val1 >>> val2      */
+               case ICMD_IAND:                         /* ..., val1, val2  ==> ..., val1 & val2        */
+               case ICMD_LAND:  
+               case ICMD_IOR:                          /* ..., val1, val2  ==> ..., val1 | val2        */
+               case ICMD_LOR:
+               case ICMD_IXOR:                         /* ..., val1, val2  ==> ..., val1 ^ val2        */
+               case ICMD_LXOR:
+                       if (temp > 0)
+                               return tracing(block, index-1, temp+1);
+                       else
+                               return create_trace(TRACE_UNKNOWN, -1, 0, index);
+                       break;
+     
+               case ICMD_LADDCONST:            /* ..., value  ==> ..., value + constant        */
+               case ICMD_LSUBCONST:            /* ..., value  ==> ..., value - constant        */
+               case ICMD_IMULCONST:            /* ..., value  ==> ..., value * constant        */
+               case ICMD_LMULCONST:            /* ..., value  ==> ..., value * constant        */
+               case ICMD_IDIVPOW2:                     /* ..., value  ==> ..., value << constant       */
+               case ICMD_LDIVPOW2:                     /* val.i = constant                                                     */
+               case ICMD_ISHLCONST:            /* ..., value  ==> ..., value << constant       */
+               case ICMD_ISHRCONST:            /* ..., value  ==> ..., value >> constant       */
+               case ICMD_IUSHRCONST:           /* ..., value  ==> ..., value >>> constant      */
+               case ICMD_LSHLCONST:            /* ..., value  ==> ..., value << constant       */
+               case ICMD_LSHRCONST:            /* ..., value  ==> ..., value >> constant       */
+               case ICMD_LUSHRCONST:           /* ..., value  ==> ..., value >>> constant      */
+               case ICMD_IANDCONST:            /* ..., value  ==> ..., value & constant        */
+               case ICMD_IREMPOW2:                     /* ..., value  ==> ..., value % constant        */
+               case ICMD_IREM0X10001:          /* ..., value  ==> ..., value % 0x100001        */
+               case ICMD_LANDCONST:            /* ..., value  ==> ..., value & constant        */
+               case ICMD_LREMPOW2:                     /* ..., value  ==> ..., value % constant        */
+               case ICMD_LREM0X10001:          /* ..., value  ==> ..., value % 0x10001         */
+               case ICMD_IORCONST:                     /* ..., value  ==> ..., value | constant        */
+               case ICMD_LORCONST:                     /* ..., value  ==> ..., value | constant        */  
+               case ICMD_IXORCONST:            /* ..., value  ==> ..., value ^ constant        */
+               case ICMD_LXORCONST:            /* ..., value  ==> ..., value ^ constant        */
+               case ICMD_LCMP:                         /* ..., val1, val2  ==> ..., val1 cmp val2      */
+                       if (temp > 0)
+                               return tracing(block, index-1, temp);
+                       else
+                               return create_trace(TRACE_UNKNOWN, -1, 0, index);
+                       break;
+
+               case ICMD_IINC:                         /* ..., value  ==> ..., value + constant        */
+                       return tracing(block, index-1, temp);
+                       break;
+
+
+               /* floating operations                                                                                                  */
+               case ICMD_FADD:                         /* ..., val1, val2  ==> ..., val1 + val2        */
+               case ICMD_DADD:                         /* ..., val1, val2  ==> ..., val1 + val2        */
+               case ICMD_FSUB:                         /* ..., val1, val2  ==> ..., val1 - val2        */
+               case ICMD_DSUB:                         /* ..., val1, val2  ==> ..., val1 - val2        */
+               case ICMD_FMUL:                         /* ..., val1, val2  ==> ..., val1 * val2        */
+               case ICMD_DMUL:                         /* ..., val1, val2  ==> ..., val1 *** val2      */
+               case ICMD_FDIV:                         /* ..., val1, val2  ==> ..., val1 / val2        */
+               case ICMD_DDIV:                         /* ..., val1, val2  ==> ..., val1 / val2        */
+               case ICMD_FREM:                         /* ..., val1, val2  ==> ..., val1 % val2        */
+               case ICMD_DREM:                         /* ..., val1, val2  ==> ..., val1 % val2        */
+               case ICMD_FCMPL:                        /* .., val1, val2  ==> ..., val1 fcmpl val2     */
+               case ICMD_DCMPL:
+               case ICMD_FCMPG:                        /* .., val1, val2  ==> ..., val1 fcmpg val2     */
+               case ICMD_DCMPG:
+                       if (temp > 0)
+                               return tracing(block, index-1, temp+1);
+                       else
+                               return create_trace(TRACE_UNKNOWN, -1, 0, index);
+                       break;
+
+               case ICMD_FNEG:                         /* ..., value  ==> ..., - value                         */
+               case ICMD_DNEG:                         /* ..., value  ==> ..., - value                         */  
+               case ICMD_I2F:                          /* ..., value  ==> ..., (float) value           */
+               case ICMD_L2F:
+               case ICMD_I2D:                          /* ..., value  ==> ..., (double) value          */
+               case ICMD_L2D:
+               case ICMD_F2I:                          /* ..., value  ==> ..., (int) value                     */
+               case ICMD_D2I:
+               case ICMD_F2L:                          /* ..., value  ==> ..., (long) value            */
+               case ICMD_D2L:  
+               case ICMD_F2D:                          /* ..., value  ==> ..., (double) value          */
+               case ICMD_D2F:                          /* ..., value  ==> ..., (double) value          */
+                       if (temp > 0)
+                               return tracing(block, index-1, temp);
+                       else
+                               return create_trace(TRACE_UNKNOWN, -1, 0, index);
+                       break;
+   
+               /* memory operations                                                                                                    */
+                case ICMD_ARRAYLENGTH:         /* ..., arrayref  ==> ..., length                       */
+                       if (temp > 0)
+                               return tracing(block, index-1, temp);
+                       else
+                               return array_length(tracing(block, index-1, 0));
+                       break;
+
+               case ICMD_AALOAD:                       /* ..., arrayref, index  ==> ..., value         */
+               case ICMD_LALOAD:                       /* ..., arrayref, index  ==> ..., value         */  
+               case ICMD_IALOAD:                       /* ..., arrayref, index  ==> ..., value         */
+               case ICMD_FALOAD:                       /* ..., arrayref, index  ==> ..., value         */
+               case ICMD_DALOAD:                       /* ..., arrayref, index  ==> ..., value         */
+               case ICMD_CALOAD:                       /* ..., arrayref, index  ==> ..., value         */
+               case ICMD_SALOAD:                       /* ..., arrayref, index  ==> ..., value         */
+               case ICMD_BALOAD:                       /* ..., arrayref, index  ==> ..., value         */
+                       if (temp > 0)           
+                               return tracing(block, index-1, temp+1);
+                       else
+                               return create_trace(TRACE_UNKNOWN, -1, 0, index);
+                       break;
+
+               case ICMD_AASTORE:                      /* ..., arrayref, index, value  ==> ...         */
+               case ICMD_LASTORE:                      /* ..., arrayref, index, value  ==> ...         */
+               case ICMD_IASTORE:                      /* ..., arrayref, index, value  ==> ...         */
+               case ICMD_FASTORE:                      /* ..., arrayref, index, value  ==> ...         */
+               case ICMD_DASTORE:                      /* ..., arrayref, index, value  ==> ...         */
+               case ICMD_CASTORE:                      /* ..., arrayref, index, value  ==> ...         */
+               case ICMD_SASTORE:                      /* ..., arrayref, index, value  ==> ...         */
+               case ICMD_BASTORE:                      /* ..., arrayref, index, value  ==> ...         */
+                       return tracing(block, index-1, temp+3);
+                       break;
+               case ICMD_PUTSTATIC:            /* ..., value  ==> ...                                          */
+               case ICMD_PUTFIELD:                     /* ..., value  ==> ...                                          */
+                       return tracing(block, index-1, temp+1);
+                       break;
+               case ICMD_GETSTATIC:            /* ...  ==> ..., value                                          */
+               case ICMD_GETFIELD:                     /* ...  ==> ..., value                                          */
+                       if (temp > 0)
+                               return tracing(block, index-1, temp-1);
+                       else
+                               return create_trace(TRACE_UNKNOWN, -1, 0, index);
+                       break;
+
+
+               /* branch: should not be encountered, but function calls possible               */
+               case ICMD_INVOKESTATIC:         /* ..., [arg1, [arg2 ...]] ==> ...                      */
+                       m = ip->val.a;                  /* get method pointer and                                       */
+                       args = ip->op1;                 /* number of arguments                                          */
+                       if (m->returntype != TYPE_VOID)
+                               retval = 1;                     /* if function returns a value, it is on        */
+                       else                                    /* top of stack                                                         */
+                               retval = 0;
+      
+                       if (temp > 0)                   /* temp is increased by number of arguments     */
+                                                                       /* less a possible result value                         */
+                               return tracing(block, index-1, temp+(args-retval));
+                       else
+                               return create_trace(TRACE_UNKNOWN, -1, 0, index);
+                       break;
+
+               case ICMD_INVOKESPECIAL:        /* ..., objectref, [arg1, [arg2 ...]] ==> .     */
+               case ICMD_INVOKEVIRTUAL:        /* ..., objectref, [arg1, [arg2 ...]] ==> .     */
+               case ICMD_INVOKEINTERFACE:      /* ..., objectref, [arg1, [arg2 ...]] ==> . */
+                       m = ip->val.a;
+                       args = ip->op1; 
+                       if (m->returntype != TYPE_VOID)
+                               retval = 1;
+                       else
+                               retval = 0;
+                       
+                       if (temp > 0)                   /* same as above but add 1 for object ref       */
+                               return tracing(block, index-1, temp+(args-retval+1));
+                       else
+                               return create_trace(TRACE_UNKNOWN, -1, 0, index);
+                       break;
+               /* special                                                                                                                              */  
+               case ICMD_INSTANCEOF:           /* ..., objectref ==> ..., intresult            */
+               case ICMD_CHECKCAST:            /* ..., objectref ==> ..., objectref            */
+                       if (temp > 0)
+                               return tracing(block, index-1, temp);
+                       else
+                               return create_trace(TRACE_UNKNOWN, -1, 0, index);
+                       break;
+      
+               case ICMD_MULTIANEWARRAY:       /* ..., cnt1, [cnt2, ...] ==> ..., arrayref     */
+                                                                       /* op1 = dimension                                                      */ 
+
+                       if (temp > 0)                   /* temp increased by number of dimensions       */
+                                                                       /* minus one for array ref                                      */
+                               return tracing(block, index-1, temp+(ip->op1 - 1));
+                       else
+                               return create_trace(TRACE_UNKNOWN, -1, 0, index);
+                       break;
+       
+               case ICMD_BUILTIN3:                     /* ..., arg1, arg2, arg3 ==> ...                        */
+                       if (ip->op1 != TYPE_VOID)
+                               retval = 1;
+                       else
+                               retval = 0;
+      
+                       if (temp > 0)                   /* increase temp by 3 minus possible return     */
+                                                                       /* value                                                                        */
+                               return tracing(block, index-1, temp+(3-retval));
+                       else
+                               return create_trace(TRACE_UNKNOWN, -1, 0, index);
+                       break;
+
+               case ICMD_BUILTIN2:                     /* ..., arg1, arg2 ==> ...                                      */
+                       if (ip->op1 != TYPE_VOID)
+                               retval = 1;
+                       else
+                               retval = 0;
+                       if (temp > 0)
+                               return tracing(block, index-1, temp+(2-retval));
+                       else
+                               return create_trace(TRACE_UNKNOWN, -1, 0, index);
+                       break;
+
+               case ICMD_BUILTIN1:     /* ..., arg1 ==> ...                                                    */
+                       if (ip->op1 != TYPE_VOID)
+                               retval = 1;
+                       else
+                               retval = 0;
+                       if (temp > 0)
+                               return tracing(block, index-1, temp+(1-retval));
+                       else
+                               return create_trace(TRACE_UNKNOWN, -1, 0, index);
+                       break;
+
+               /* others                                                                                                                               */
+               default:
+                       return create_trace(TRACE_UNKNOWN, -1, 0, index);
+                       }       /* switch       */
+               }               /* if           */
+       else
+               return create_trace(TRACE_UNKNOWN, -1, 0, index);
+}
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
index bc093f63dbd4b1eef7491220df3c4a5070733230..6f50fff21c4e9623212eb0a842db852fa333c4c2 100644 (file)
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4 from Makefile.am
+# Makefile.in generated automatically by automake 1.3 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -11,7 +11,7 @@
 # PARTICULAR PURPOSE.
 
 
-SHELL = @SHELL@
+SHELL = /bin/sh
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -32,7 +32,7 @@ mandir = @mandir@
 includedir = @includedir@
 oldincludedir = /usr/include
 
-DESTDIR =
+DISTDIR =
 
 pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -46,7 +46,7 @@ AUTOMAKE = @AUTOMAKE@
 AUTOHEADER = @AUTOHEADER@
 
 INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 transform = @program_transform_name@
@@ -81,13 +81,14 @@ DIST_COMMON =  Makefile.am Makefile.in
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = tar
-GZIP_ENV = --best
-all: all-redirect
+GZIP = --best
+all: Makefile
+
 .SUFFIXES:
-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-       cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps nat/Makefile
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu nat/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -100,75 +101,67 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = nat
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu nat/Makefile
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
-         if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
-         else \
-           test -f $(distdir)/$$file \
-           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
-           || cp -p $$d/$$file $(distdir)/$$file || :; \
-         fi; \
+         test -f $(distdir)/$$file \
+         || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+         || cp -p $$d/$$file $(distdir)/$$file; \
        done
-info-am:
-info: info-am
-dvi-am:
-dvi: dvi-am
-check-am: all-am
-check: check-am
-installcheck-am:
-installcheck: installcheck-am
-install-exec-am:
-install-exec: install-exec-am
-
-install-data-am:
-install-data: install-data-am
-
-install-am: all-am
-       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-install: install-am
-uninstall-am:
-uninstall: uninstall-am
-all-am: Makefile
-all-redirect: all-am
+info:
+dvi:
+check: all
+       $(MAKE)
+installcheck:
+install-exec: 
+       @$(NORMAL_INSTALL)
+
+install-data: 
+       @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+       @:
+
+uninstall: 
+
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+       $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
 installdirs:
 
 
 mostlyclean-generic:
+       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
 
 clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
-       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f Makefile $(DISTCLEANFILES)
        -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
 
 maintainer-clean-generic:
-mostlyclean-am:  mostlyclean-generic
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean:  mostlyclean-generic
 
-mostlyclean: mostlyclean-am
+clean:  clean-generic mostlyclean
 
-clean-am:  clean-generic mostlyclean-am
+distclean:  distclean-generic clean
+       -rm -f config.status
 
-clean: clean-am
-
-distclean-am:  distclean-generic clean-am
-
-distclean: distclean-am
-
-maintainer-clean-am:  maintainer-clean-generic distclean-am
+maintainer-clean:  maintainer-clean-generic distclean
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
-maintainer-clean: maintainer-clean-am
-
-.PHONY: tags distdir info-am info dvi-am dvi check check-am \
-installcheck-am installcheck install-exec-am install-exec \
-install-data-am install-data install-am install uninstall-am uninstall \
-all-redirect all-am all installdirs mostlyclean-generic \
-distclean-generic clean-generic maintainer-clean-generic clean \
-mostlyclean distclean maintainer-clean
+.PHONY: tags distdir info dvi installcheck install-exec install-data \
+install uninstall all installdirs mostlyclean-generic distclean-generic \
+clean-generic maintainer-clean-generic clean mostlyclean distclean \
+maintainer-clean
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
index 30534360cae9f069fc2cf5a37eb1144630f27932..82ce1e0783fd23de1e6030ca6767adfb337c3156 100644 (file)
@@ -17,7 +17,7 @@
                 Mark Probst         EMAIL: cacao@complang.tuwien.ac.at
                         Philipp Tomsich     EMAIL: cacao@complang.tuwien.ac.at
 
-       Last Change: $Id: cacao.c 123 1999-01-28 19:48:49Z phil $
+       Last Change: $Id: cacao.c 132 1999-09-27 15:54:42Z chris $
 
 *******************************************************************************/
 
@@ -89,6 +89,7 @@ void **stackbottom = 0;
 #define OPT_GC1         22
 #define OPT_GC2         23
 #endif
+#define OPT_OLOOP       24
 
 struct {char *name; bool arg; int value;} opts[] = {
        {"classpath",   true,   OPT_CLASSPATH},
@@ -121,6 +122,7 @@ struct {char *name; bool arg; int value;} opts[] = {
        {"gc1",         false,  OPT_GC1},
        {"gc2",         false,  OPT_GC2},
 #endif
+       {"oloop",       false,  OPT_OLOOP},
        {NULL,  false, 0}
 };
 
@@ -198,6 +200,7 @@ static void print_usage()
        printf ("          -log logfile ......... specify a name for the logfile\n");
        printf ("          -c(heck)b(ounds) ..... don't check array bounds\n");
        printf ("                  s(ync) ....... don't check for synchronization\n");
+       printf ("          -oloop ............... optimize array accesses in loops\n"); 
        printf ("          -l ................... don't start the class after loading\n");
        printf ("          -all ................. compile all methods, no execution\n");
 #ifdef OLD_COMPILER
@@ -675,6 +678,10 @@ int main(int argc, char **argv)
                        }
                        break;
                        
+               case OPT_OLOOP:
+                       opt_loops = true;
+                       break;
+
                default:
                        print_usage();
                        exit(10);
index 0cdf4817bab7c8233145b09cfb2c0586cc07bf62..a5e7c0db879d7fcae87584ac23648ccb3b2a7956 100644 (file)
@@ -12,7 +12,7 @@
        Changes: Mark     Probst  (schani)   EMAIL: cacao@complang.tuwien.ac.at
                         Philipp  Tomsich (phil)     EMAIL: cacao@complang.tuwien.ac.at
 
-       Last Change: $Id: global.h 118 1999-01-20 14:58:16Z andi $
+       Last Change: $Id: global.h 132 1999-09-27 15:54:42Z chris $
 
 *******************************************************************************/
 
@@ -336,9 +336,27 @@ typedef struct fieldinfo {/* field of a class                                 */
 
 } fieldinfo;
 
+struct basicblock;
 
 /* exceptiontable *************************************************************/
 
+typedef struct xtable { /* exceptiontable entry in a method           */ 
+       s4         startpc;         /* start pc of guarded area (inclusive)       */
+       struct basicblock *start;
+
+       s4         endpc;           /* end pc of guarded area (exklusive)         */
+       struct basicblock *end;
+
+       s4         handlerpc;       /* pc of exception handler                    */
+       struct basicblock *handler;
+
+       classinfo *catchtype;       /* catchtype of exception (NULL == catchall)  */
+       struct xtable *next;        /* used to build a list of exception when     */
+                                   /* loops are copied */
+       struct xtable *down;        /* instead of the old array, a list is used   */
+} xtable;
+
+
 typedef struct exceptiontable { /* exceptiontable entry in a method           */ 
        s4         startpc;         /* start pc of guarded area (inclusive)       */
        s4         endpc;           /* end pc of guarded area (exklusive)         */
@@ -365,7 +383,8 @@ typedef struct methodinfo {         /* method structure                       */
        u1        *jcode;               /* pointer to JavaVM code                 */
 
        s4         exceptiontablelength;/* exceptiontable length                  */
-       exceptiontable *exceptiontable; /* the exceptiontable                     */
+       exceptiontable *exceptiontable; 
+                                    /* the exceptiontable                     */
 
        u1        *stubroutine;         /* stub for compiling or calling natives  */    
        s4         mcodelength;         /* legth of generated machine code        */
index f9860e08c02f9c737d343207e8016537f0dd14c6..958068eb3b8b424da749681b4ce8741b08fec16a 100644 (file)
@@ -8,7 +8,7 @@
        
        Author: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
 
-       Last Change: $Id: parse.c 115 1999-01-20 01:52:45Z phil $
+       Last Change: $Id: parse.c 132 1999-09-27 15:54:42Z chris $
 
 *******************************************************************************/
 
@@ -288,7 +288,7 @@ static void parse()
        /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
        /* additional MONITOREXITS are reached by branches which are 3 bytes */
        
-       iptr = instr = DMNEW(instruction, jcodelength + 5);
+       iptr = instr = DMNEW(instruction, jcodelength + 5); 
        
        /* initialize block_index table (unrolled four times) */
 
@@ -305,19 +305,34 @@ static void parse()
 
        /* compute branch targets of exception table */
 
+       extable = DMNEW(xtable, exceptiontablelength + 1);
+
        for (i = 0; i < exceptiontablelength; i++) {
-               p = extable[i].startpc;
+
+               p = extable[i].startpc = raw_extable[i].startpc;
                bound_check(p);
                block_insert(p);
-               p = extable[i].endpc;
+
+               p = extable[i].endpc = raw_extable[i].endpc;
                bound_check1(p);
                if (p < jcodelength)
                        block_insert(p);
-               p = extable[i].handlerpc;
+
+               p = extable[i].handlerpc = raw_extable[i].handlerpc;
                bound_check(p);
                block_insert(p);
+
+               extable[i].catchtype  = raw_extable[i].catchtype;
+
+               extable[i].next = NULL;
+               extable[i].down = &extable[i+1];
                }
 
+       if (exceptiontablelength > 0)
+               extable[exceptiontablelength-1].down = NULL;
+       else
+               extable = NULL;
+
        s_count = 1 + exceptiontablelength; /* initialize stack element counter   */
 
 #ifdef USE_THREADS
@@ -1066,6 +1081,7 @@ static void parse()
        bptr = block = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
 
        b_count = 0;
+       c_debug_nr = 0;
        
        /* additional block if target 0 is not first intermediate instruction     */
 
@@ -1076,37 +1092,69 @@ static void parse()
                bptr->type = BBTYPE_STD;
                bptr->branchrefs = NULL;
                bptr->pre_count = 0;
+               bptr->debug_nr = c_debug_nr++;
                bptr++;
                b_count++;
+               (bptr - 1)->next = bptr;
+       
                }
 
        /* allocate blocks */
 
+
        for (p = 0; p < jcodelength; p++)
+               
                if (block_index[p] & 1) {
                        bptr->iinstr = instr + (block_index[p] >> 1);
+                       bptr->debug_nr = c_debug_nr++;
                        if (b_count != 0)
                                (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
                        bptr->mpc = -1;
                        bptr->flags = -1;
+                       bptr->lflags = 0;
                        bptr->type = BBTYPE_STD;
                        bptr->branchrefs = NULL;
                        block_index[p] = b_count;
                        bptr->pre_count = 0;
                        bptr++;
                        b_count++;
+
+                       (bptr - 1)->next = bptr;
                        }
 
        /* allocate additional block at end */
 
+       
+       bptr->instack = bptr->outstack = NULL;
+       bptr->indepth = bptr->outdepth = 0;
        bptr->iinstr = NULL;
        (bptr - 1)->icount = (instr + instr_count) - (bptr - 1)->iinstr;
        bptr->icount = 0;
        bptr->mpc = -1;
        bptr->flags = -1;
+       bptr->lflags = 0;
        bptr->type = BBTYPE_STD;
        bptr->branchrefs = NULL;
        bptr->pre_count = 0;
+       bptr->debug_nr = c_debug_nr++;
+                       
+       (bptr - 1)->next = bptr;
+       bptr->next = NULL;
+
+       last_block = bptr;
+
+
+
+       for (i = 0; i < exceptiontablelength; ++i) {
+               p = extable[i].startpc;
+               extable[i].start = block + block_index[p];
+
+               p = extable[i].endpc;
+               extable[i].end = block + block_index[p]; 
+
+               p = extable[i].handlerpc;
+               extable[i].handler = block + block_index[p];
+           }
        }
 }
 
index 17ee4ed81750147f6fd2cbdc3b3ce47846e4e9d8..dd9fc35dd1a73d2ffc16bd7d1cda4a2a6a34001f 100644 (file)
@@ -17,7 +17,7 @@
 #else
 #define COUNT(cnt)
 #endif
-
 #define STACKRESET {curstack=0;stackdepth=0;}
 
 #define TYPEPANIC  {show_icmd_method();panic("Stack type mismatch");}
@@ -164,7 +164,9 @@ static void analyse_stack()
        int superblockend, repeat, deadcode;
        instruction *iptr = instr;
        basicblock *bptr, *tbptr;
-       s4  *s4ptr;
+       s4 *s4ptr;
+       void* *tptr;
+       xtable *ex;
        
        arguments_num = 0;
        new = stack;
@@ -290,6 +292,7 @@ static void analyse_stack()
                                b_index = bptr - block;
                                while (--len >= 0)  {
                                        opcode = iptr->opc;
+                                       iptr->target = NULL;
                                        switch (opcode) {
 
                                                /* pop 0 push 0 */
@@ -472,6 +475,9 @@ icmd_if_icmp_tail:
                                                                                /* iptr[1].opc = ICMD_NOP; */
                                                                                OP1_0(TYPE_INT);
                                                                                tbptr = block + block_index[iptr->op1];
+
+                                                                               iptr[0].target = (void *) tbptr;
+
                                                                                MARKREACHED(tbptr, copy);
                                                                                COUNT(count_pcmd_bra);
                                                                                break;
@@ -656,6 +662,9 @@ icmd_lconst_lcmp_tail:
                                                                                                iptr[2].opc = ICMD_NOP; */
                                                                                                OP1_0(TYPE_LNG);
                                                                                                tbptr = block + block_index[iptr->op1];
+
+                                                                                               iptr[0].target = (void *) tbptr;
+
                                                                                                MARKREACHED(tbptr, copy);
                                                                                                COUNT(count_pcmd_bra);
                                                                                                COUNT(count_pcmd_op);
@@ -858,6 +867,9 @@ icmd_lconst_lcmp_tail:
                                                        COUNT(count_pcmd_bra);
                                                        OP1_0(TYPE_ADR);
                                                        tbptr = block + block_index[iptr->op1];
+
+                                                       iptr[0].target = (void *) tbptr;
+
                                                        MARKREACHED(tbptr, copy);
                                                        break;
 
@@ -927,6 +939,9 @@ icmd_lconst_lcmp_tail:
 #endif
                                                        OP1_0(TYPE_INT);
                                                        tbptr = block + block_index[iptr->op1];
+
+                                                       iptr[0].target = (void *) tbptr;
+
                                                        MARKREACHED(tbptr, copy);
                                                        break;
 
@@ -935,6 +950,9 @@ icmd_lconst_lcmp_tail:
                                                case ICMD_GOTO:
                                                        COUNT(count_pcmd_bra);
                                                        tbptr = block + block_index[iptr->op1];
+
+                                                       iptr[0].target = (void *) tbptr;
+
                                                        MARKREACHED(tbptr, copy);
                                                        SETDST;
                                                        superblockend = true;
@@ -950,8 +968,19 @@ icmd_lconst_lcmp_tail:
                                                        MARKREACHED(tbptr, copy);
                                                        i = *s4ptr++;                          /* low     */
                                                        i = *s4ptr++ - i + 1;                  /* high    */
+
+                                                       tptr = DMNEW(void*, i+1);
+                                                       iptr->target = (void *) tptr;
+
+                                                       tptr[0] = (void *) tbptr;
+                                                       tptr++;
+
                                                        while (--i >= 0) {
                                                                tbptr = block + block_index[*s4ptr++];
+
+                                                               tptr[0] = (void *) tbptr;
+                                                               tptr++;
+
                                                                MARKREACHED(tbptr, copy);
                                                                }
                                                        SETDST;
@@ -967,8 +996,19 @@ icmd_lconst_lcmp_tail:
                                                        tbptr = block + block_index[*s4ptr++]; /* default */
                                                        MARKREACHED(tbptr, copy);
                                                        i = *s4ptr++;                          /* count   */
+
+                                                       tptr = DMNEW(void*, i+1);
+                                                       iptr->target = (void *) tptr;
+
+                                                       tptr[0] = (void *) tbptr;
+                                                       tptr++;
+
                                                        while (--i >= 0) {
                                                                tbptr = block + block_index[s4ptr[1]];
+
+                                                               tptr[0] = (void *) tbptr;
+                                                               tptr++;
+                                                               
                                                                MARKREACHED(tbptr, copy);
                                                                s4ptr += 2;
                                                                }
@@ -994,6 +1034,9 @@ icmd_lconst_lcmp_tail:
                                                        COUNT(count_pcmd_bra);
                                                        OP2_0(TYPE_INT);
                                                        tbptr = block + block_index[iptr->op1];
+                                                       
+                                                       iptr[0].target = (void *) tbptr;
+
                                                        MARKREACHED(tbptr, copy);
                                                        break;
 
@@ -1002,6 +1045,9 @@ icmd_lconst_lcmp_tail:
                                                        COUNT(count_pcmd_bra);
                                                        OP2_0(TYPE_ADR);
                                                        tbptr = block + block_index[iptr->op1];
+
+                                                       iptr[0].target = (void *) tbptr;
+
                                                        MARKREACHED(tbptr, copy);
                                                        break;
 
@@ -1201,6 +1247,9 @@ icmd_lcmp_if_tail:
                                                                                /* iptr[1].opc = ICMD_NOP; */
                                                                                OP2_0(TYPE_LNG);
                                                                                tbptr = block + block_index[iptr->op1];
+                       
+                                                                               iptr[0].target = (void *) tbptr;
+
                                                                                MARKREACHED(tbptr, copy);
                                                                                COUNT(count_pcmd_bra);
                                                                                break;
@@ -1342,6 +1391,9 @@ icmd_lcmp_if_tail:
                                                case ICMD_JSR:
                                                        OP0_1(TYPE_ADR);
                                                        tbptr = block + block_index[iptr->op1];
+
+                                                       iptr[0].target = (void *) tbptr;
+
                                                        tbptr->type=BBTYPE_SBR;
                                                        MARKREACHED(tbptr, copy);
                                                        OP1_0ANY;
@@ -1467,8 +1519,8 @@ builtin2:
                        else
                                count_block_stack[bptr->indepth]++;
                        len = bptr->icount;
-                       if (len <= 10) 
-                               count_block_size_distribution[len - 1]++;
+                       if (len < 10) 
+                               count_block_size_distribution[len]++;
                        else if (len <= 12)
                                count_block_size_distribution[10]++;
                        else if (len <= 14)
@@ -1658,11 +1710,14 @@ static char *jit_type[] = {
 
 static void show_icmd_method()
 {
-       int b, i, j, last;
+       int i, j, last;
        int deadcode;
        s4  *s4ptr;
        instruction *iptr;
-       
+       basicblock *bptr;
+       void **tptr;
+       xtable *ex;
+
        printf("\n");
        unicode_fprint(stdout, class->name);
        printf(".");
@@ -1672,11 +1727,11 @@ static void show_icmd_method()
        printf ("\n\nMax locals: %d\n", (int) maxlocals);
        printf ("Max stack:  %d\n", (int) maxstack);
 
-       printf ("Exceptions:\n");
-       for (i = 0; i < exceptiontablelength; i++) {
-               printf("    L%03d ... ", block_index[extable[i].startpc]);
-               printf("L%03d = ", block_index[extable[i].endpc]);
-               printf("L%03d\n", block_index[extable[i].handlerpc]);
+       printf ("Exceptions (Number: %d):\n", exceptiontablelength);
+       for (ex = extable; ex != NULL; ex = ex->down) {
+               printf("    L%03d ... ", ex->start->debug_nr );
+               printf("L%03d  = ", ex->end->debug_nr);
+               printf("L%03d\n", ex->handler->debug_nr);
                }
        
        printf ("Local Table:\n");
@@ -1735,19 +1790,20 @@ static void show_icmd_method()
                printf("\n");
                }
 
-       for (b = 0; b < block_count; b++)
-               if (block[b].flags != BBDELETED) {
-               deadcode = block[b].flags <= BBREACHED;
+       
+       for (bptr = block; bptr != NULL; bptr = bptr->next)
+               if (bptr->flags != BBDELETED) {
+               deadcode = bptr->flags <= BBREACHED;
                printf("[");
                if (deadcode)
                        for (j = maxstack; j > 0; j--)
                                printf(" ?  ");
                else
-                       print_stack(block[b].instack);
-               printf("] L%03d(%d):\n", b, block[b].pre_count);
-               iptr = block[b].iinstr;
-               i = iptr - instr;
-               for (last = i + block[b].icount; i < last; i++, iptr++) {
+                       print_stack(bptr->instack);
+               printf("] L%03d(%d - %d):\n", bptr->debug_nr, bptr->icount, bptr->pre_count);
+               iptr = bptr->iinstr;
+
+               for (i=0; i < bptr->icount; i++, iptr++) {
                        printf("[");
                        if (deadcode) {
                                for (j = maxstack; j > 0; j--)
@@ -1814,6 +1870,28 @@ static void show_icmd_method()
                                case ICMD_IINC:
                                        printf(" %d + %d", iptr->op1, iptr->val.i);
                                        break;
+
+                           case ICMD_IASTORE:
+                           case ICMD_SASTORE:
+                           case ICMD_BASTORE:
+                           case ICMD_CASTORE:
+                           case ICMD_LASTORE:
+                           case ICMD_DASTORE:
+                           case ICMD_FASTORE:
+                           case ICMD_AASTORE:
+
+                           case ICMD_IALOAD:
+                           case ICMD_SALOAD:
+                           case ICMD_BALOAD:
+                           case ICMD_CALOAD:
+                           case ICMD_LALOAD:
+                           case ICMD_DALOAD:
+                           case ICMD_FALOAD:
+                           case ICMD_AALOAD:
+                                       if (iptr->op1 != 0)
+                                               printf("(opt.)");
+                                       break;
+
                                case ICMD_RET:
                                case ICMD_ILOAD:
                                case ICMD_LLOAD:
@@ -1906,7 +1984,7 @@ static void show_icmd_method()
                                case ICMD_IF_LGE:
                                case ICMD_IF_LGT:
                                case ICMD_IF_LLE:
-                                       printf("(%d) L%03d", iptr->val.i, block_index[iptr->op1]);
+                                       printf("(%d) L%03d", iptr->val.i, ((basicblock *) iptr->target)->debug_nr);
                                        break;
                                case ICMD_JSR:
                                case ICMD_GOTO:
@@ -1926,25 +2004,39 @@ static void show_icmd_method()
                                case ICMD_IF_LCMPLE:
                                case ICMD_IF_ACMPEQ:
                                case ICMD_IF_ACMPNE:
-                                       printf(" L%03d", block_index[iptr->op1]);
+                                       printf(" L%03d", ((basicblock *) iptr->target)->debug_nr);
                                        break;
                                case ICMD_TABLESWITCH:
+
                                        s4ptr = iptr->val.a;
-                                       printf(" L%03d;", block_index[*s4ptr++]); /* default */
+                                       tptr = (void **) iptr->target;
+
+                                       printf(" L%03d;", ((basicblock *) *tptr)->debug_nr); 
+                                                                                   /* default */
+
+                                       s4ptr++;
+                                       tptr++;
+
                                        j = *s4ptr++;                               /* low     */
                                        j = *s4ptr++ - j;                           /* high    */
                                        while (j >= 0) {
-                                               printf(" L%03d", block_index[*s4ptr++]);
+                                               printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
+                                               tptr++;
                                                j--;
                                                }
                                        break;
                                case ICMD_LOOKUPSWITCH:
                                        s4ptr = iptr->val.a;
-                                       printf(" L%d", block_index[*s4ptr++]);   /* default */
-                                       j = *s4ptr++;                               /* count   */
+                                       tptr = (void **) iptr->target;
+
+                                       printf(" L%03d", ((basicblock *) *tptr)->debug_nr); 
+                                       s4ptr++;                                         /* default */
+                                       j = *s4ptr;                                      /* count   */
+                                       tptr++;
+
                                        while (--j >= 0) {
-                                               printf(" L%03d", block_index[s4ptr[1]]);
-                                               s4ptr += 2;
+                                               printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
+                                               tptr++;
                                                }
                                        break;
                                }
@@ -1953,15 +2045,26 @@ static void show_icmd_method()
 
                if (showdisassemble && (!deadcode)) {
                        printf("\n");
-                       i = block[b].mpc;
+                       i = bptr->mpc;
                        s4ptr = (s4 *) (method->mcode + dseglen + i);
-                       for (; i < block[b + 1].mpc; i += 4, s4ptr++) {
-                               disassinstr(*s4ptr, i); 
-                               }
-                       printf("\n");
-                       }
+
+                       if (bptr->next != NULL) {
+                               for (; i < bptr->next->mpc; i += 4, s4ptr++) {
+                                       disassinstr(*s4ptr, i); 
+                                   }
+                               printf("\n");
+                           }
+                       else {
+                               for (; s4ptr < (s4 *) (method->mcode + method->mcodelength); i += 4, s4ptr++) {
+                                       disassinstr(*s4ptr, i); 
+                                   }
+                               printf("\n");
+                           }
+                   }
        }
-       i = block[b].mpc;
+
+       /*
+       i = bptr->mpc;
        s4ptr = (s4 *) (method->mcode + dseglen + i);
        if (showdisassemble && (s4ptr < (s4 *) (method->mcode + method->mcodelength))) {
                printf("\n");
@@ -1970,6 +2073,7 @@ static void show_icmd_method()
                        }
                printf("\n");
                }
+       */
 }
 
 
index 49aa1e8d0762f237c30f3bd686c1bcf6934f4770..2b30d9c95437c03ec0af17b75671d6f801e296ff 100644 (file)
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4 from Makefile.am
+# Makefile.in generated automatically by automake 1.3 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -11,7 +11,7 @@
 # PARTICULAR PURPOSE.
 
 
-SHELL = @SHELL@
+SHELL = /bin/sh
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -32,7 +32,7 @@ mandir = @mandir@
 includedir = @includedir@
 oldincludedir = /usr/include
 
-DESTDIR =
+DISTDIR =
 
 pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -46,7 +46,7 @@ AUTOMAKE = @AUTOMAKE@
 AUTOHEADER = @AUTOHEADER@
 
 INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 transform = @program_transform_name@
@@ -81,13 +81,14 @@ DIST_COMMON =  Makefile.am Makefile.in
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = tar
-GZIP_ENV = --best
-all: all-redirect
+GZIP = --best
+all: Makefile
+
 .SUFFIXES:
-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-       cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps tst/Makefile
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu tst/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -100,75 +101,67 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = tst
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu tst/Makefile
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
-         if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
-         else \
-           test -f $(distdir)/$$file \
-           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
-           || cp -p $$d/$$file $(distdir)/$$file || :; \
-         fi; \
+         test -f $(distdir)/$$file \
+         || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+         || cp -p $$d/$$file $(distdir)/$$file; \
        done
-info-am:
-info: info-am
-dvi-am:
-dvi: dvi-am
-check-am: all-am
-check: check-am
-installcheck-am:
-installcheck: installcheck-am
-install-exec-am:
-install-exec: install-exec-am
-
-install-data-am:
-install-data: install-data-am
-
-install-am: all-am
-       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-install: install-am
-uninstall-am:
-uninstall: uninstall-am
-all-am: Makefile
-all-redirect: all-am
+info:
+dvi:
+check: all
+       $(MAKE)
+installcheck:
+install-exec: 
+       @$(NORMAL_INSTALL)
+
+install-data: 
+       @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+       @:
+
+uninstall: 
+
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+       $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
 installdirs:
 
 
 mostlyclean-generic:
+       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
 
 clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
-       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f Makefile $(DISTCLEANFILES)
        -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
 
 maintainer-clean-generic:
-mostlyclean-am:  mostlyclean-generic
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean:  mostlyclean-generic
 
-mostlyclean: mostlyclean-am
+clean:  clean-generic mostlyclean
 
-clean-am:  clean-generic mostlyclean-am
+distclean:  distclean-generic clean
+       -rm -f config.status
 
-clean: clean-am
-
-distclean-am:  distclean-generic clean-am
-
-distclean: distclean-am
-
-maintainer-clean-am:  maintainer-clean-generic distclean-am
+maintainer-clean:  maintainer-clean-generic distclean
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
-maintainer-clean: maintainer-clean-am
-
-.PHONY: tags distdir info-am info dvi-am dvi check check-am \
-installcheck-am installcheck install-exec-am install-exec \
-install-data-am install-data install-am install uninstall-am uninstall \
-all-redirect all-am all installdirs mostlyclean-generic \
-distclean-generic clean-generic maintainer-clean-generic clean \
-mostlyclean distclean maintainer-clean
+.PHONY: tags distdir info dvi installcheck install-exec install-data \
+install uninstall all installdirs mostlyclean-generic distclean-generic \
+clean-generic maintainer-clean-generic clean mostlyclean distclean \
+maintainer-clean
 
 
 check: 
index 5ba14eecf003fb3bb45be250b3f65b456f462752..b08880884c4f15ce815eb8f84d67af6872f8e63a 100644 (file)
@@ -432,7 +432,6 @@ public class jctest implements jcinterface {
        // ************************ test array bounds ******************************            
 
        public static void testarraybounds(byte[] ba, int i) {
-               
                        p ("testarraybounds: " + (i - 10));
                        ba[i-10] = 0;
                        p ("testarraybounds: " + (i - 5));
@@ -442,7 +441,7 @@ public class jctest implements jcinterface {
                        p ("testarraybounds: " + (i + 5));
                        ba[i+5]  = 0;
                        p ("testarraybounds: " + (i + 10));
-                       ba[i+10] = 0;
+                       ba[i+10] = 0; 
                }
 
 
@@ -494,7 +493,7 @@ public class jctest implements jcinterface {
                        p ("error: exception not thrown");
                        }       
                catch (ArrayIndexOutOfBoundsException c) {
-                       p ("exception: out of bounds: "+(-1));
+                       p ("exception_1: out of bounds: "+(-1));
                        }
                try {
                        p ("array bound check: byte array load");
@@ -502,63 +501,68 @@ public class jctest implements jcinterface {
                        p ("error: exception not thrown");
                        }       
                catch (ArrayIndexOutOfBoundsException c) {
-                       p ("exception: out of bounds: "+(-1));
+                       p ("exception_2: out of bounds: "+(-1));
                        }
 
                try {
                        testarraybounds(ba, 5);
                        }       
                catch (ArrayIndexOutOfBoundsException c) {
-                       p ("exception: out of bounds: "+5);
+                       p ("exception_3: out of bounds: "+5);
                        }
                try {
                        testarraybounds(ba, 50);
                        }       
                catch (ArrayIndexOutOfBoundsException c) {
-                       p ("exception: out of bounds: "+50);
+                       p ("exception_4: out of bounds: "+50);
                        }
                try {
                        testarraybounds(ba, 100);
                        }       
                catch (ArrayIndexOutOfBoundsException c) {
-                       p ("exception: out of bounds: "+100);
+                       p ("exception_5: out of bounds: "+100);
                        }
 
                try {
                        ba[-4] = 0;
                        }       
                catch (ArrayIndexOutOfBoundsException c) {
-                       p ("exception: out of bounds: "+(-4));
+                       p ("exception_6: out of bounds: "+(-4));
                        }
                try {
                        ba[-3] = 0;
                        }       
                catch (ArrayIndexOutOfBoundsException c) {
-                       p ("exception: out of bounds: "+(-3));
+                       p ("exception_7: out of bounds: "+(-3));
                        }
+               System.out.println("starting 8. loop");
+
                for (i=-2; i<102; i++) { 
                        try {
                                ba[i] = (byte) (i-50);
                                }       
                        catch (ArrayIndexOutOfBoundsException c) {
-                               p ("exception: out of bounds: "+i);
+                               p ("exception_8: out of bounds: "+i);
                                }
                        }
+               
                try {
                        ba[102] = 0;
                        }       
                catch (ArrayIndexOutOfBoundsException c) {
-                       p ("exception: out of bounds: "+102);
+                       p ("exception_9: out of bounds: "+102);
                        }
                try {
                        ba[103] = 0;
                        }       
                catch (ArrayIndexOutOfBoundsException c) {
-                       p ("exception: out of bounds: "+103);
+                       p ("exception_10: out of bounds: "+103);
                        }
                for (i=0; i<100; i++) p (ba[i]);                
 
 
+               
+
                p ("-------- test short arrays");               
 
                short[] sa = null;
@@ -588,7 +592,7 @@ public class jctest implements jcinterface {
                        p ("error: exception not thrown");
                        }       
                catch (ArrayIndexOutOfBoundsException c) {
-                       p ("exception: out of bounds: "+(-1));
+                       p ("exception_11: out of bounds: "+(-1));
                        }
                try {
                        p ("array bound check: short array load");
@@ -596,12 +600,13 @@ public class jctest implements jcinterface {
                        p ("error: exception not thrown");
                        }       
                catch (ArrayIndexOutOfBoundsException c) {
-                       p ("exception: out of bounds: "+(-1));
+                       p ("exception_12: out of bounds: "+(-1));
                        }
 
                for (i=0; i<100; i++) sa[i] = (short) (i-50);
                for (i=0; i<100; i++) p (sa[i]);
                
+               
 
                p ("-------- test int arrays");         
 
@@ -818,9 +823,8 @@ public class jctest implements jcinterface {
                                        }
                                }
                        }
+               
 
-
-                                       
                }
 
 
index 200bb05ed4ed15cc42a7204cc2701b07ca735dc8..6b8cc26671b412d27ebe13323123deb74bbd6ad1 100644 (file)
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4 from Makefile.am
+# Makefile.in generated automatically by automake 1.3 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -11,7 +11,7 @@
 # PARTICULAR PURPOSE.
 
 
-SHELL = @SHELL@
+SHELL = /bin/sh
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -32,7 +32,7 @@ mandir = @mandir@
 includedir = @includedir@
 oldincludedir = /usr/include
 
-DESTDIR =
+DISTDIR =
 
 pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -46,7 +46,7 @@ AUTOMAKE = @AUTOMAKE@
 AUTOHEADER = @AUTOHEADER@
 
 INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 transform = @program_transform_name@
@@ -74,10 +74,11 @@ VERSION = @VERSION@
 noinst_LIBRARIES = @LIBTHREAD@
 EXTRA_LIBRARIES = libthreads.a
 
-libthreads_a_SOURCES = locks.c locks.h                        thread.c thread.h                       threadio.c threadio.h
+libthreads_a_SOURCES = locks.c locks.h \
+                      thread.c thread.h \
+                      threadio.c threadio.h
 
-
-INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/@SYSDEP_DIR@
+INCLUDES=-I$(top_srcdir) -I$(top_srcdir)/@SYSDEP_DIR@
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = ../config.h
 CONFIG_CLEAN_FILES = 
@@ -92,26 +93,27 @@ libthreads_a_LIBADD =
 libthreads_a_OBJECTS =  locks.o thread.o threadio.o
 AR = ar
 CFLAGS = @CFLAGS@
-COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
 DIST_COMMON =  Makefile.am Makefile.in
 
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = tar
-GZIP_ENV = --best
+GZIP = --best
+DEP_FILES =  .deps/locks.P .deps/thread.P .deps/threadio.P
 SOURCES = $(libthreads_a_SOURCES)
 OBJECTS = $(libthreads_a_OBJECTS)
 
-all: all-redirect
+all: Makefile $(LIBRARIES)
+
 .SUFFIXES:
 .SUFFIXES: .S .c .o .s
-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-       cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps threads/Makefile
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu threads/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -125,9 +127,6 @@ distclean-noinstLIBRARIES:
 
 maintainer-clean-noinstLIBRARIES:
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -152,12 +151,8 @@ libthreads.a: $(libthreads_a_OBJECTS) $(libthreads_a_DEPENDENCIES)
 tags: TAGS
 
 ID: $(HEADERS) $(SOURCES) $(LISP)
-       list='$(SOURCES) $(HEADERS)'; \
-       unique=`for i in $$list; do echo $$i; done | \
-         awk '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
        here=`pwd` && cd $(srcdir) \
-         && mkid -f$$here/ID $$unique $(LISP)
+         && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
 
 TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
        tags=; \
@@ -183,84 +178,102 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = threads
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu threads/Makefile
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
-         if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
-         else \
-           test -f $(distdir)/$$file \
-           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
-           || cp -p $$d/$$file $(distdir)/$$file || :; \
-         fi; \
+         test -f $(distdir)/$$file \
+         || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+         || cp -p $$d/$$file $(distdir)/$$file; \
        done
-info-am:
-info: info-am
-dvi-am:
-dvi: dvi-am
-check-am: all-am
-check: check-am
-installcheck-am:
-installcheck: installcheck-am
-install-exec-am:
-install-exec: install-exec-am
-
-install-data-am:
-install-data: install-data-am
-
-install-am: all-am
-       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-install: install-am
-uninstall-am:
-uninstall: uninstall-am
-all-am: Makefile $(LIBRARIES)
-all-redirect: all-am
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+
+maintainer-clean-depend:
+       -rm -rf .deps
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).P -c $<
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).p -c $<
+       @-sed -e 's/^\([^:]*\)\.o:/\1.lo \1.o:/' \
+         < .deps/$(*F).p > .deps/$(*F).P
+       @-rm -f .deps/$(*F).p
+info:
+dvi:
+check: all
+       $(MAKE)
+installcheck:
+install-exec: 
+       @$(NORMAL_INSTALL)
+
+install-data: 
+       @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+       @:
+
+uninstall: 
+
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+       $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
 installdirs:
 
 
 mostlyclean-generic:
+       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
 
 clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
-       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f Makefile $(DISTCLEANFILES)
        -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
 
 maintainer-clean-generic:
-mostlyclean-am:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
-               mostlyclean-tags mostlyclean-generic
-
-mostlyclean: mostlyclean-am
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
+               mostlyclean-tags mostlyclean-depend mostlyclean-generic
 
-clean-am:  clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
-               mostlyclean-am
+clean:  clean-noinstLIBRARIES clean-compile clean-tags clean-depend \
+               clean-generic mostlyclean
 
-clean: clean-am
+distclean:  distclean-noinstLIBRARIES distclean-compile distclean-tags \
+               distclean-depend distclean-generic clean
+       -rm -f config.status
 
-distclean-am:  distclean-noinstLIBRARIES distclean-compile \
-               distclean-tags distclean-generic clean-am
-
-distclean: distclean-am
-
-maintainer-clean-am:  maintainer-clean-noinstLIBRARIES \
+maintainer-clean:  maintainer-clean-noinstLIBRARIES \
                maintainer-clean-compile maintainer-clean-tags \
-               maintainer-clean-generic distclean-am
+               maintainer-clean-depend maintainer-clean-generic \
+               distclean
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
-maintainer-clean: maintainer-clean-am
-
 .PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
 clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
 mostlyclean-compile distclean-compile clean-compile \
 maintainer-clean-compile tags mostlyclean-tags distclean-tags \
-clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
-check-am installcheck-am installcheck install-exec-am install-exec \
-install-data-am install-data install-am install uninstall-am uninstall \
-all-redirect all-am all installdirs mostlyclean-generic \
-distclean-generic clean-generic maintainer-clean-generic clean \
-mostlyclean distclean maintainer-clean
+clean-tags maintainer-clean-tags distdir mostlyclean-depend \
+distclean-depend clean-depend maintainer-clean-depend info dvi \
+installcheck install-exec install-data install uninstall all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
index c76ca7024177eab08a2e50b951b804dd62a4c241..898911f6480604c8236b7fbd0557bf6675499192 100644 (file)
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4 from Makefile.am
+# Makefile.in generated automatically by automake 1.3 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -11,7 +11,7 @@
 # PARTICULAR PURPOSE.
 
 
-SHELL = @SHELL@
+SHELL = /bin/sh
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -32,7 +32,7 @@ mandir = @mandir@
 includedir = @includedir@
 oldincludedir = /usr/include
 
-DESTDIR =
+DISTDIR =
 
 pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -46,7 +46,7 @@ AUTOMAKE = @AUTOMAKE@
 AUTOHEADER = @AUTOHEADER@
 
 INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 transform = @program_transform_name@
@@ -73,10 +73,13 @@ VERSION = @VERSION@
 
 noinst_LIBRARIES = libtoolbox.a
 
-libtoolbox_a_SOURCES = memory.c memory.h                      loging.c loging.h                       chain.c chain.h                 tree.c tree.h                   list.c list.h
+libtoolbox_a_SOURCES = memory.c memory.h \
+                      loging.c loging.h \
+                      chain.c chain.h \
+                      tree.c tree.h \
+                      list.c list.h
 
-
-INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/@SYSDEP_DIR@
+INCLUDES=-I$(top_srcdir) -I$(top_srcdir)/@SYSDEP_DIR@
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = ../config.h
 CONFIG_CLEAN_FILES = 
@@ -91,26 +94,28 @@ libtoolbox_a_LIBADD =
 libtoolbox_a_OBJECTS =  memory.o loging.o chain.o tree.o list.o
 AR = ar
 CFLAGS = @CFLAGS@
-COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
 DIST_COMMON =  Makefile.am Makefile.in
 
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = tar
-GZIP_ENV = --best
+GZIP = --best
+DEP_FILES =  .deps/chain.P .deps/list.P .deps/loging.P .deps/memory.P \
+.deps/tree.P
 SOURCES = $(libtoolbox_a_SOURCES)
 OBJECTS = $(libtoolbox_a_OBJECTS)
 
-all: all-redirect
+all: Makefile $(LIBRARIES)
+
 .SUFFIXES:
 .SUFFIXES: .S .c .o .s
-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-       cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps toolbox/Makefile
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu toolbox/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -124,9 +129,6 @@ distclean-noinstLIBRARIES:
 
 maintainer-clean-noinstLIBRARIES:
 
-.c.o:
-       $(COMPILE) -c $<
-
 .s.o:
        $(COMPILE) -c $<
 
@@ -151,12 +153,8 @@ libtoolbox.a: $(libtoolbox_a_OBJECTS) $(libtoolbox_a_DEPENDENCIES)
 tags: TAGS
 
 ID: $(HEADERS) $(SOURCES) $(LISP)
-       list='$(SOURCES) $(HEADERS)'; \
-       unique=`for i in $$list; do echo $$i; done | \
-         awk '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
        here=`pwd` && cd $(srcdir) \
-         && mkid -f$$here/ID $$unique $(LISP)
+         && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
 
 TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
        tags=; \
@@ -182,84 +180,102 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 subdir = toolbox
 
 distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu toolbox/Makefile
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
-         if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
-         else \
-           test -f $(distdir)/$$file \
-           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
-           || cp -p $$d/$$file $(distdir)/$$file || :; \
-         fi; \
+         test -f $(distdir)/$$file \
+         || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+         || cp -p $$d/$$file $(distdir)/$$file; \
        done
-info-am:
-info: info-am
-dvi-am:
-dvi: dvi-am
-check-am: all-am
-check: check-am
-installcheck-am:
-installcheck: installcheck-am
-install-exec-am:
-install-exec: install-exec-am
-
-install-data-am:
-install-data: install-data-am
-
-install-am: all-am
-       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-install: install-am
-uninstall-am:
-uninstall: uninstall-am
-all-am: Makefile $(LIBRARIES)
-all-redirect: all-am
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+
+maintainer-clean-depend:
+       -rm -rf .deps
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).P -c $<
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).p -c $<
+       @-sed -e 's/^\([^:]*\)\.o:/\1.lo \1.o:/' \
+         < .deps/$(*F).p > .deps/$(*F).P
+       @-rm -f .deps/$(*F).p
+info:
+dvi:
+check: all
+       $(MAKE)
+installcheck:
+install-exec: 
+       @$(NORMAL_INSTALL)
+
+install-data: 
+       @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+       @:
+
+uninstall: 
+
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+       $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
 installdirs:
 
 
 mostlyclean-generic:
+       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
 
 clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
-       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f Makefile $(DISTCLEANFILES)
        -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
 
 maintainer-clean-generic:
-mostlyclean-am:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
-               mostlyclean-tags mostlyclean-generic
-
-mostlyclean: mostlyclean-am
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
+               mostlyclean-tags mostlyclean-depend mostlyclean-generic
 
-clean-am:  clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
-               mostlyclean-am
+clean:  clean-noinstLIBRARIES clean-compile clean-tags clean-depend \
+               clean-generic mostlyclean
 
-clean: clean-am
+distclean:  distclean-noinstLIBRARIES distclean-compile distclean-tags \
+               distclean-depend distclean-generic clean
+       -rm -f config.status
 
-distclean-am:  distclean-noinstLIBRARIES distclean-compile \
-               distclean-tags distclean-generic clean-am
-
-distclean: distclean-am
-
-maintainer-clean-am:  maintainer-clean-noinstLIBRARIES \
+maintainer-clean:  maintainer-clean-noinstLIBRARIES \
                maintainer-clean-compile maintainer-clean-tags \
-               maintainer-clean-generic distclean-am
+               maintainer-clean-depend maintainer-clean-generic \
+               distclean
        @echo "This command is intended for maintainers to use;"
        @echo "it deletes files that may require special tools to rebuild."
 
-maintainer-clean: maintainer-clean-am
-
 .PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
 clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
 mostlyclean-compile distclean-compile clean-compile \
 maintainer-clean-compile tags mostlyclean-tags distclean-tags \
-clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
-check-am installcheck-am installcheck install-exec-am install-exec \
-install-data-am install-data install-am install uninstall-am uninstall \
-all-redirect all-am all installdirs mostlyclean-generic \
-distclean-generic clean-generic maintainer-clean-generic clean \
-mostlyclean distclean maintainer-clean
+clean-tags maintainer-clean-tags distdir mostlyclean-depend \
+distclean-depend clean-depend maintainer-clean-depend info dvi \
+installcheck install-exec install-data install uninstall all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.