From criswell at cs.uiuc.edu Mon Aug 25 10:05:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Aug 25 10:05:01 2003 Subject: [llvm-commits] CVS: llvm/test/QMTestDB/regression.qms/tablegen.qms/2003-08-03-passcode.qmt bitsinitoverflow.qmt cstylecomment.qmt generallist.qmt include.qmt intbitinit.qmt listconversion.qmt tree.qmt treenames.qmt unterminatedcomment.qmt Message-ID: <200308251504.KAA20322@choi.cs.uiuc.edu> Changes in directory llvm/test/QMTestDB/regression.qms/tablegen.qms: 2003-08-03-passcode.qmt added (r1.1) bitsinitoverflow.qmt added (r1.1) cstylecomment.qmt added (r1.1) generallist.qmt added (r1.1) include.qmt added (r1.1) intbitinit.qmt added (r1.1) listconversion.qmt added (r1.1) tree.qmt added (r1.1) treenames.qmt added (r1.1) unterminatedcomment.qmt added (r1.1) --- Log message: Adding the tablegen tests to the QMTest test suite. --- Diffs of the changes: Index: llvm/test/QMTestDB/regression.qms/tablegen.qms/2003-08-03-passcode.qmt diff -c /dev/null llvm/test/QMTestDB/regression.qms/tablegen.qms/2003-08-03-passcode.qmt:1.1 *** /dev/null Mon Aug 25 10:04:48 2003 --- llvm/test/QMTestDB/regression.qms/tablegen.qms/2003-08-03-passcode.qmt Mon Aug 25 10:04:38 2003 *************** *** 0 **** --- 1,2 ---- + + .*test/Regression/TableGen/2003-08-03-PassCode.td Index: llvm/test/QMTestDB/regression.qms/tablegen.qms/bitsinitoverflow.qmt diff -c /dev/null llvm/test/QMTestDB/regression.qms/tablegen.qms/bitsinitoverflow.qmt:1.1 *** /dev/null Mon Aug 25 10:04:48 2003 --- llvm/test/QMTestDB/regression.qms/tablegen.qms/bitsinitoverflow.qmt Mon Aug 25 10:04:38 2003 *************** *** 0 **** --- 1,2 ---- + + .*test/Regression/TableGen/BitsInitOverflow.td Index: llvm/test/QMTestDB/regression.qms/tablegen.qms/cstylecomment.qmt diff -c /dev/null llvm/test/QMTestDB/regression.qms/tablegen.qms/cstylecomment.qmt:1.1 *** /dev/null Mon Aug 25 10:04:48 2003 --- llvm/test/QMTestDB/regression.qms/tablegen.qms/cstylecomment.qmt Mon Aug 25 10:04:38 2003 *************** *** 0 **** --- 1,2 ---- + + .*test/Regression/TableGen/CStyleComment.td Index: llvm/test/QMTestDB/regression.qms/tablegen.qms/generallist.qmt diff -c /dev/null llvm/test/QMTestDB/regression.qms/tablegen.qms/generallist.qmt:1.1 *** /dev/null Mon Aug 25 10:04:48 2003 --- llvm/test/QMTestDB/regression.qms/tablegen.qms/generallist.qmt Mon Aug 25 10:04:38 2003 *************** *** 0 **** --- 1,2 ---- + + .*test/Regression/TableGen/GeneralList.td Index: llvm/test/QMTestDB/regression.qms/tablegen.qms/include.qmt diff -c /dev/null llvm/test/QMTestDB/regression.qms/tablegen.qms/include.qmt:1.1 *** /dev/null Mon Aug 25 10:04:48 2003 --- llvm/test/QMTestDB/regression.qms/tablegen.qms/include.qmt Mon Aug 25 10:04:38 2003 *************** *** 0 **** --- 1,2 ---- + + .*test/Regression/TableGen/Include.td Index: llvm/test/QMTestDB/regression.qms/tablegen.qms/intbitinit.qmt diff -c /dev/null llvm/test/QMTestDB/regression.qms/tablegen.qms/intbitinit.qmt:1.1 *** /dev/null Mon Aug 25 10:04:48 2003 --- llvm/test/QMTestDB/regression.qms/tablegen.qms/intbitinit.qmt Mon Aug 25 10:04:38 2003 *************** *** 0 **** --- 1,2 ---- + + .*test/Regression/TableGen/IntBitInit.td Index: llvm/test/QMTestDB/regression.qms/tablegen.qms/listconversion.qmt diff -c /dev/null llvm/test/QMTestDB/regression.qms/tablegen.qms/listconversion.qmt:1.1 *** /dev/null Mon Aug 25 10:04:48 2003 --- llvm/test/QMTestDB/regression.qms/tablegen.qms/listconversion.qmt Mon Aug 25 10:04:38 2003 *************** *** 0 **** --- 1,2 ---- + + .*test/Regression/TableGen/ListConversion.td Index: llvm/test/QMTestDB/regression.qms/tablegen.qms/tree.qmt diff -c /dev/null llvm/test/QMTestDB/regression.qms/tablegen.qms/tree.qmt:1.1 *** /dev/null Mon Aug 25 10:04:48 2003 --- llvm/test/QMTestDB/regression.qms/tablegen.qms/tree.qmt Mon Aug 25 10:04:38 2003 *************** *** 0 **** --- 1,2 ---- + + .*test/Regression/TableGen/Tree.td Index: llvm/test/QMTestDB/regression.qms/tablegen.qms/treenames.qmt diff -c /dev/null llvm/test/QMTestDB/regression.qms/tablegen.qms/treenames.qmt:1.1 *** /dev/null Mon Aug 25 10:04:48 2003 --- llvm/test/QMTestDB/regression.qms/tablegen.qms/treenames.qmt Mon Aug 25 10:04:38 2003 *************** *** 0 **** --- 1,2 ---- + + .*test/Regression/TableGen/TreeNames.td Index: llvm/test/QMTestDB/regression.qms/tablegen.qms/unterminatedcomment.qmt diff -c /dev/null llvm/test/QMTestDB/regression.qms/tablegen.qms/unterminatedcomment.qmt:1.1 *** /dev/null Mon Aug 25 10:04:48 2003 --- llvm/test/QMTestDB/regression.qms/tablegen.qms/unterminatedcomment.qmt Mon Aug 25 10:04:38 2003 *************** *** 0 **** --- 1,2 ---- + + .*test/Regression/TableGen/UnterminatedComment.td From criswell at cs.uiuc.edu Mon Aug 25 10:05:05 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Aug 25 10:05:05 2003 Subject: [llvm-commits] CVS: llvm/test/QMTestDB/regression.qms/tablegen.qms/ Message-ID: <200308251504.KAA20289@choi.cs.uiuc.edu> Changes in directory llvm/test/QMTestDB/regression.qms/tablegen.qms: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/QMTestDB/regression.qms/tablegen.qms added to the repository --- Diffs of the changes: From criswell at cs.uiuc.edu Mon Aug 25 10:22:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Aug 25 10:22:01 2003 Subject: [llvm-commits] CVS: llvm/test/QMTestDB/regression.qms/transforms.qms/decomposemultidimrefs.qms/multidim.qmt Message-ID: <200308251521.KAA20369@choi.cs.uiuc.edu> Changes in directory llvm/test/QMTestDB/regression.qms/transforms.qms/decomposemultidimrefs.qms: multidim.qmt added (r1.1) --- Log message: Adding to the QMTest based test suite. --- Diffs of the changes: Index: llvm/test/QMTestDB/regression.qms/transforms.qms/decomposemultidimrefs.qms/multidim.qmt diff -c /dev/null llvm/test/QMTestDB/regression.qms/transforms.qms/decomposemultidimrefs.qms/multidim.qmt:1.1 *** /dev/null Mon Aug 25 10:21:55 2003 --- llvm/test/QMTestDB/regression.qms/transforms.qms/decomposemultidimrefs.qms/multidim.qmt Mon Aug 25 10:21:45 2003 *************** *** 0 **** --- 1,2 ---- + + .*test/Regression/Transforms/DecomposeMultiDimRefs/multidim.ll From criswell at cs.uiuc.edu Mon Aug 25 10:22:02 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Aug 25 10:22:02 2003 Subject: [llvm-commits] CVS: llvm/test/QMTestDB/regression.qms/transforms.qms/decomposemultidimrefs.qms/ Message-ID: <200308251521.KAA20355@choi.cs.uiuc.edu> Changes in directory llvm/test/QMTestDB/regression.qms/transforms.qms/decomposemultidimrefs.qms: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/QMTestDB/regression.qms/transforms.qms/decomposemultidimrefs.qms added to the repository --- Diffs of the changes: From criswell at cs.uiuc.edu Mon Aug 25 11:51:02 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Aug 25 11:51:02 2003 Subject: [llvm-commits] CVS: llvm/autoconf/configure.ac Message-ID: <200308251650.LAA12627@choi.cs.uiuc.edu> Changes in directory llvm/autoconf: configure.ac updated: 1.5 -> 1.6 --- Log message: Added code to check for python and qmtest. Added code that verifies that GCC is version 3.0 or higher. --- Diffs of the changes: Index: llvm/autoconf/configure.ac diff -u llvm/autoconf/configure.ac:1.5 llvm/autoconf/configure.ac:1.6 --- llvm/autoconf/configure.ac:1.5 Thu Aug 14 13:59:53 2003 +++ llvm/autoconf/configure.ac Mon Aug 25 11:49:54 2003 @@ -93,6 +93,13 @@ AC_MSG_ERROR([g++ required but not found]) fi +dnl Verify that GCC is version 3.0 or higher +gccmajor=`$CC --version | head -n 1 | awk '{print $NF;}' | cut -d. -f1` +if test "$gccmajor" -lt "3" +then + AC_MSG_ERROR([gcc 3.x required]) +fi + dnl Check for GNU Make. We use its extensions to, so don't build without it CHECK_GNU_MAKE if test -z "$_cv_gnu_make_command" @@ -108,6 +115,7 @@ AC_PROG_LIBTOOL dnl Check for our special programs +AC_PATH_PROG(RPWD,[pwd]) AC_PATH_PROG(AR,[ar]) AC_PATH_PROG(SED,[sed]) AC_PATH_PROG(RM,[rm]) @@ -118,6 +126,26 @@ AC_PATH_PROG(DOT,[dot]) AC_PATH_PROG(ETAGS,[etags]) AC_PATH_PROG(PURIFY,[purify]) +AC_PATH_PROG(PYTHON,[python]) +AC_PATH_PROG(QMTEST,[qmtest]) + +dnl Verify that the version of python available is high enough for qmtest +pyversion=`$PYTHON -V 2>&1 | cut -d\ -f2` +pymajor=`echo $pyversion | cut -d. -f1` +pyminor=`echo $pyversion | cut -d. -f2` + +if test "$pymajor" -ge "2" +then + if test "$pymajor" -eq "2" + then + if test "$pyminor" -lt "2" + then + AC_MSG_ERROR([Python 2.2 or greater required]) + fi + fi +else + AC_MSG_ERROR([Python 2.2 or greater required]) +fi dnl Verify that the source directory is valid AC_CONFIG_SRCDIR(["Makefile.config.in"]) @@ -324,6 +352,10 @@ fi AC_ARG_WITH(objroot,AC_HELP_STRING([--with-objroot],[Location where object files should be placed (default is .)]),AC_SUBST(OBJROOT,[$withval])) + +dnl ************************************************************************** +dnl * Configure other software packages (via AC_CONFIG_SUBDIRS) +dnl ************************************************************************** dnl ************************************************************************** dnl * Create the output files From criswell at cs.uiuc.edu Mon Aug 25 11:51:04 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Aug 25 11:51:04 2003 Subject: [llvm-commits] CVS: llvm/configure Message-ID: <200308251650.LAA12620@choi.cs.uiuc.edu> Changes in directory llvm: configure updated: 1.12 -> 1.13 --- Log message: Added code to check for python and qmtest. Added code that verifies that GCC is version 3.0 or higher. --- Diffs of the changes: Index: llvm/configure diff -u llvm/configure:1.12 llvm/configure:1.13 --- llvm/configure:1.12 Thu Jul 31 11:45:35 2003 +++ llvm/configure Mon Aug 25 11:49:50 2003 @@ -464,7 +464,7 @@ #endif" ac_unique_file=""Makefile.config.in"" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os OS LLVMGCCDIR ARCH CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT CC CFLAGS ac_ct_CC CPP ifGNUmake LEX LEXLIB LEX_OUTPUT_ROOT YACC EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL SED RM MKDIR DATE MV DOT ETAGS PURIFY ALLOCA LIBOBJS MMAP_FILE ENABLE_PURIFY ENABLE_OPTIMIZED USE_SPEC UPB DISABLE_LLC_DIFFS JIT SPEC_ROOT BCR PAPIDIR OBJROOT LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os OS LLVMGCCDIR ARCH CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT CC CFLAGS ac_ct_CC CPP ifGNUmake LEX LEXLIB LEX_OUTPUT_ROOT YACC EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL RPWD SED RM MKDIR DATE MV DOT ETAGS PURIFY PYTHON QMTEST ALLOCA LIBOBJS MMAP_FILE ENABLE_PURIFY ENABLE_OPTIMIZED USE_SPEC UPB DISABLE_LLC_DIFFS JIT SPEC_ROOT BCR PAPIDIR OBJROOT LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -2930,6 +2930,14 @@ { (exit 1); exit 1; }; } fi +gccmajor=`$CC --version | head -n 1 | awk '{print $NF;}' | cut -d. -f1` +if test "$gccmajor" -lt "3" +then + { { echo "$as_me:$LINENO: error: gcc 3.x required" >&5 +echo "$as_me: error: gcc 3.x required" >&2;} + { (exit 1); exit 1; }; } +fi + echo "$as_me:$LINENO: checking for GNU make" >&5 echo $ECHO_N "checking for GNU make... $ECHO_C" >&6 if test "${_cv_gnu_make_command+set}" = set; then @@ -3852,7 +3860,7 @@ ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 3855 "configure"' > conftest.$ac_ext + echo '#line 3863 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -4693,7 +4701,7 @@ # Provide some information about the compiler. -echo "$as_me:4696:" \ +echo "$as_me:4704:" \ "checking for Fortran 77 compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 @@ -5702,11 +5710,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:5705: $lt_compile\"" >&5) + (eval echo "\"\$as_me:5713: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:5709: \$? = $ac_status" >&5 + echo "$as_me:5717: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -5934,11 +5942,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:5937: $lt_compile\"" >&5) + (eval echo "\"\$as_me:5945: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:5941: \$? = $ac_status" >&5 + echo "$as_me:5949: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -6001,11 +6009,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6004: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6012: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:6008: \$? = $ac_status" >&5 + echo "$as_me:6016: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -8013,7 +8021,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:10258: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:10254: \$? = $ac_status" >&5 + echo "$as_me:10262: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -10314,11 +10322,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:10317: $lt_compile\"" >&5) + (eval echo "\"\$as_me:10325: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:10321: \$? = $ac_status" >&5 + echo "$as_me:10329: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -11557,7 +11565,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:12488: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:12484: \$? = $ac_status" >&5 + echo "$as_me:12492: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -12544,11 +12552,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12547: $lt_compile\"" >&5) + (eval echo "\"\$as_me:12555: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:12551: \$? = $ac_status" >&5 + echo "$as_me:12559: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14488,11 +14496,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14491: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14499: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14495: \$? = $ac_status" >&5 + echo "$as_me:14503: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -14720,11 +14728,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14723: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14731: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14727: \$? = $ac_status" >&5 + echo "$as_me:14735: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -14787,11 +14795,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14790: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14798: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14794: \$? = $ac_status" >&5 + echo "$as_me:14802: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -16799,7 +16807,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_RPWD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $RPWD in + [\\/]* | ?:[\\/]*) + ac_cv_path_RPWD="$RPWD" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_RPWD="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + ;; +esac +fi +RPWD=$ac_cv_path_RPWD + +if test -n "$RPWD"; then + echo "$as_me:$LINENO: result: $RPWD" >&5 +echo "${ECHO_T}$RPWD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 @@ -18294,6 +18341,105 @@ echo "${ECHO_T}no" >&6 fi +# Extract the first word of "python", so it can be a program name with args. +set dummy python; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_PYTHON+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $PYTHON in + [\\/]* | ?:[\\/]*) + ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + ;; +esac +fi +PYTHON=$ac_cv_path_PYTHON + +if test -n "$PYTHON"; then + echo "$as_me:$LINENO: result: $PYTHON" >&5 +echo "${ECHO_T}$PYTHON" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +# Extract the first word of "qmtest", so it can be a program name with args. +set dummy qmtest; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_QMTEST+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $QMTEST in + [\\/]* | ?:[\\/]*) + ac_cv_path_QMTEST="$QMTEST" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_QMTEST="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + ;; +esac +fi +QMTEST=$ac_cv_path_QMTEST + +if test -n "$QMTEST"; then + echo "$as_me:$LINENO: result: $QMTEST" >&5 +echo "${ECHO_T}$QMTEST" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + +pyversion=`$PYTHON -V 2>&1 | cut -d\ -f2` +pymajor=`echo $pyversion | cut -d. -f1` +pyminor=`echo $pyversion | cut -d. -f2` + +if test "$pymajor" -ge "2" +then + if test "$pymajor" -eq "2" + then + if test "$pyminor" -lt "2" + then + { { echo "$as_me:$LINENO: error: Python 2.2 or greater required" >&5 +echo "$as_me: error: Python 2.2 or greater required" >&2;} + { (exit 1); exit 1; }; } + fi + fi +else + { { echo "$as_me:$LINENO: error: Python 2.2 or greater required" >&5 +echo "$as_me: error: Python 2.2 or greater required" >&2;} + { (exit 1); exit 1; }; } +fi @@ -22067,7 +22213,7 @@ PAPIDIR=$withval else - PAPIDIR=/home/vadve/shared/papi-2.3.4.1 + PAPIDIR=/home/vadve/shared/Sparc/papi-2.3.4.1 fi; @@ -22102,6 +22248,7 @@ fi; + ac_config_files="$ac_config_files Makefile.config" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -22761,6 +22908,7 @@ s, at FFLAGS@,$FFLAGS,;t t s, at ac_ct_F77@,$ac_ct_F77,;t t s, at LIBTOOL@,$LIBTOOL,;t t +s, at RPWD@,$RPWD,;t t s, at SED@,$SED,;t t s, at RM@,$RM,;t t s, at MKDIR@,$MKDIR,;t t @@ -22769,6 +22917,8 @@ s, at DOT@,$DOT,;t t s, at ETAGS@,$ETAGS,;t t s, at PURIFY@,$PURIFY,;t t +s, at PYTHON@,$PYTHON,;t t +s, at QMTEST@,$QMTEST,;t t s, at ALLOCA@,$ALLOCA,;t t s, at LIBOBJS@,$LIBOBJS,;t t s, at MMAP_FILE@,$MMAP_FILE,;t t From criswell at cs.uiuc.edu Mon Aug 25 11:53:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Aug 25 11:53:01 2003 Subject: [llvm-commits] CVS: llvm/www/docs/ReleaseTasks.html Message-ID: <200308251651.LAA14806@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: ReleaseTasks.html updated: 1.8 -> 1.9 --- Log message: Added autoconf code that verifies that the C compiler is at the minimum supported version (3.x). --- Diffs of the changes: Index: llvm/www/docs/ReleaseTasks.html diff -u llvm/www/docs/ReleaseTasks.html:1.8 llvm/www/docs/ReleaseTasks.html:1.9 --- llvm/www/docs/ReleaseTasks.html:1.8 Thu Aug 21 10:25:55 2003 +++ llvm/www/docs/ReleaseTasks.html Mon Aug 25 11:51:44 2003 @@ -118,7 +118,6 @@
  • Move the Reoptimizer code out of mainline CVS and the release.
  • -
  • Add autoconf checks to ensure that the compiler is GCC 3.x or higher.
  • Documentation
  • From gaeke at cs.uiuc.edu Mon Aug 25 12:30:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Aug 25 12:30:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Linker/2003-08-23-RecursiveOpaqueTypeResolve.ll Message-ID: <200308251729.MAA10874@trinity.cs.uiuc.edu> Changes in directory llvm/test/Regression/Linker: 2003-08-23-RecursiveOpaqueTypeResolve.ll updated: 1.1 -> 1.2 --- Log message: Fix spelling error in comment. --- Diffs of the changes: Index: llvm/test/Regression/Linker/2003-08-23-RecursiveOpaqueTypeResolve.ll diff -u llvm/test/Regression/Linker/2003-08-23-RecursiveOpaqueTypeResolve.ll:1.1 llvm/test/Regression/Linker/2003-08-23-RecursiveOpaqueTypeResolve.ll:1.2 --- llvm/test/Regression/Linker/2003-08-23-RecursiveOpaqueTypeResolve.ll:1.1 Sat Aug 23 16:13:26 2003 +++ llvm/test/Regression/Linker/2003-08-23-RecursiveOpaqueTypeResolve.ll Mon Aug 25 12:29:40 2003 @@ -1,4 +1,4 @@ -; It's a bad idea to go recursively trapesing through types without a safety +; It's a bad idea to go recursively traipsing through types without a safety ; net. ; RUN: as < %s > Output/%s.out1.bc From lattner at cs.uiuc.edu Mon Aug 25 17:35:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 25 17:35:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/InlineFunction.cpp Message-ID: <200308252234.RAA10300@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: InlineFunction.cpp updated: 1.4 -> 1.5 --- Log message: Remove special casing --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/InlineFunction.cpp diff -u llvm/lib/Transforms/Utils/InlineFunction.cpp:1.4 llvm/lib/Transforms/Utils/InlineFunction.cpp:1.5 --- llvm/lib/Transforms/Utils/InlineFunction.cpp:1.4 Sun Aug 24 07:24:11 2003 +++ llvm/lib/Transforms/Utils/InlineFunction.cpp Mon Aug 25 17:34:15 2003 @@ -211,9 +211,6 @@ } break; // Done with this basic block! - } else if (ID == LLVMIntrinsic::exc_setcurrent || - ID == LLVMIntrinsic::exc_getcurrent) { - ShouldInvokify = false; // Not correct to invokify exc.throw! } // If we should convert this function into an invoke instruction, do From lattner at cs.uiuc.edu Mon Aug 25 17:36:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 25 17:36:00 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/Makefile c++-exception.cpp c++-exception.h exception.h Message-ID: <200308252235.RAA10562@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: Makefile added (r1.1) c++-exception.cpp added (r1.1) c++-exception.h added (r1.1) exception.h added (r1.1) --- Log message: Initial checking of C++ exception handling library --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/Makefile diff -c /dev/null llvm/runtime/GCCLibraries/libexception/Makefile:1.1 *** /dev/null Mon Aug 25 17:35:47 2003 --- llvm/runtime/GCCLibraries/libexception/Makefile Mon Aug 25 17:35:36 2003 *************** *** 0 **** --- 1,17 ---- + LEVEL = ../../.. + BYTECODE_LIBRARY=1 + DONT_BUILD_RELINKED=1 + LIBRARYNAME=exception + + #Source = crtend.c listend.ll + + ###EXPORTED_SYMBOL_LIST = __main,llvm.global_ctors,llvm.global_dtors + + include $(LEVEL)/Makefile.common + + + $(LLVMGCCDIR)/bytecode-libs/crtend.o: $(LIBNAME_BC) + @cp $< $@ + + install:: $(LLVMGCCDIR)/bytecode-libs/crtend.o + @rm $(LLVMGCCDIR)/bytecode-libs/libcrtend.bc Index: llvm/runtime/GCCLibraries/libexception/c++-exception.cpp diff -c /dev/null llvm/runtime/GCCLibraries/libexception/c++-exception.cpp:1.1 *** /dev/null Mon Aug 25 17:35:47 2003 --- llvm/runtime/GCCLibraries/libexception/c++-exception.cpp Mon Aug 25 17:35:36 2003 *************** *** 0 **** --- 1,223 ---- + //===- c++-exception.cpp - Exception handling support for C++ exceptions --===// + // + // This file defines the methods used to implement C++ exception handling in + // terms of the invoke and %llvm.unwind intrinsic. These primitives implement + // an exception handling ABI similar (but simpler and more efficient than) the + // Itanium C++ ABI exception handling standard. + // + //===----------------------------------------------------------------------===// + + #include "c++-exception.h" + #include + #include + + //===----------------------------------------------------------------------===// + // Generic exception support + // + + // Thread local state for exception handling. + // FIXME: This should really be made thread-local! + // + static llvm_exception *CaughtExceptionStack = 0; + + // UncaughtExceptionStack - The stack of exceptions currently being thrown. + static llvm_exception *UncaughtExceptionStack = 0; + + // __llvm_eh_has_uncaught_exception - This is used to implement + // std::uncaught_exception. + // + bool __llvm_eh_has_uncaught_exception(void) { + return UncaughtExceptionStack != 0; + } + + // __llvm_eh_current_uncaught_exception - This function checks to see if the + // current uncaught exception is of the specified language type. If so, it + // returns a pointer to the exception area data. + // + void *__llvm_eh_current_uncaught_exception_type(unsigned HandlerType) { + assert(UncaughtExceptionStack && "No uncaught exception!"); + if (UncaughtExceptionStack->ExceptionType == HandlerType) + return UncaughtExceptionStack+1; + return 0; + } + + + /*===----------------------------------------------------------------------===** + * C++ Specific exception handling support... + */ + + // __llvm_cxxeh_allocate_exception - This function allocates space for the + // specified number of bytes, plus a C++ exception object header. + // + void *__llvm_cxxeh_allocate_exception(unsigned NumBytes) { + // FIXME: This should eventually have back-up buffers for out-of-memory + // situations. + // + llvm_cxx_exception *E = + (llvm_cxx_exception *)malloc(NumBytes+sizeof(llvm_cxx_exception)); + E->BaseException.ExceptionType = 0; // intialize to invalid + + return E+1; // return the pointer after the header + } + + // __llvm_cxxeh_free_exception - Low-level function to free an exception. This + // is called directly from generated C++ code if evaluating the exception value + // into the exception location throws. Otherwise it is called from the C++ + // exception object destructor. + // + void __llvm_cxxeh_free_exception(void *ObjectPtr) { + llvm_cxx_exception *E = (llvm_cxx_exception *)ObjectPtr - 1; + free(E); + } + + // cxx_destructor - This function is called through the generic + // exception->ExceptionDestructor function pointer to destroy a caught + // exception. + // + static void cxx_destructor(llvm_exception *LE) { + void *ObjectPtr = LE+1; + llvm_cxx_exception *E = (llvm_cxx_exception *)ObjectPtr - 1; + + // The exception is no longer caught. + assert(CaughtExceptionStack == LE && + "Destroying an exception which is not the current caught exception?"); + CaughtExceptionStack = LE->Next; + + struct ExceptionFreer { + void *Ptr; + ExceptionFreer(void *P) : Ptr(P) {} + ~ExceptionFreer() { + // Free the memory for the exception, when the function is left, even if + // the exception object dtor throws its own exception! + __llvm_cxxeh_free_exception(Ptr); + } + } EF(E+1); + + // Run the exception object dtor if it exists. */ + if (E->ExceptionObjectDestructor) + E->ExceptionObjectDestructor(E); + } + + // __llvm_cxxeh_throw - Given a pointer to memory which has an exception object + // evaluated into it, this sets up all of the fields of the exception allowing + // it to be thrown. After calling this, the code should call %llvm.unwind + // + void __llvm_cxxeh_throw(void *ObjectPtr, const std::type_info *TypeInfoPtr, + void (*DtorPtr)(void*)) { + llvm_cxx_exception *E = (llvm_cxx_exception *)ObjectPtr - 1; + E->BaseException.ExceptionDestructor = cxx_destructor; + E->BaseException.ExceptionType = CXXException; + E->BaseException.Next = UncaughtExceptionStack; + UncaughtExceptionStack = &E->BaseException; + E->BaseException.HandlerCount = 0; + + E->TypeInfo = TypeInfoPtr; + E->ExceptionObjectDestructor = DtorPtr; + E->UnexpectedHandler = 0; /* FIXME */ + E->TerminateHandler = 0; /* FIXME */ + } + + // __llvm_cxxeh_current_uncaught_exception_isa - This function checks to see if + // the current uncaught exception is a C++ exception, and if it is of the + // specified type id. If so, it returns a pointer to the object adjusted as + // appropriate, otherwise it returns null. + // + void *__llvm_cxxeh_current_uncaught_exception_isa( + const std::type_info *CatchType) { + assert(UncaughtExceptionStack && "No uncaught exception!"); + if (UncaughtExceptionStack->ExceptionType != CXXException) + return 0; /* If it's not a c++ exception, it doesn't match! */ + + // If it is a C++ exception, use the type info object stored in the exception + // to see if TypeID matches and, if so, to adjust the exception object + // pointer. + // + llvm_cxx_exception *E = (llvm_cxx_exception*)UncaughtExceptionStack; + + // ThrownPtr is a pointer to the object being thrown... + void *ThrownPtr = E+1; + const std::type_info *ThrownType = E->TypeInfo; + + // FIXME: this code exists in the GCC exception handling library: I haven't + // thought about this yet, so it should be verified at some point! + #if 1 + // Pointer types need to adjust the actual pointer, not + // the pointer to pointer that is the exception object. + // This also has the effect of passing pointer types + // "by value" through the __cxa_begin_catch return value. + if (ThrownType->__is_pointer_p()) + ThrownPtr = *(void **)ThrownPtr; + #endif + + if (CatchType->__do_catch(ThrownType, &ThrownPtr, 1)) + return ThrownPtr; + + return 0; + } + + + /* __llvm_cxxeh_begin_catch - This function is called by "exception handlers", + * which transition an exception from being uncaught to being caught. It + * returns a pointer to the exception object portion of the exception. This + * function must work with foreign exceptions. + */ + void *__llvm_cxxeh_begin_catch(void) { + llvm_exception *E = UncaughtExceptionStack; + assert(UncaughtExceptionStack && "There are no uncaught exceptions!?!?"); + + /* The exception is now no longer uncaught... */ + UncaughtExceptionStack = E->Next; + + /* The exception is now caught... */ + E->Next = CaughtExceptionStack; + CaughtExceptionStack = E->Next; + + /* Increment the handler count for this exception. */ + E->HandlerCount++; + + /* Return a pointer to the exception object */ + return E+1; + } + + /* __llvm_cxxeh_end_catch - This function decrements the HandlerCount of the + * top-level caught exception, destroying it if this is the last handler for the + * exception. + */ + void __llvm_cxxeh_end_catch(void) { + llvm_exception *E = CaughtExceptionStack; + assert(E && "There are no caught exceptions!"); + + /* If this is the last handler using the exception, destroy it now! */ + if (--E->HandlerCount == 0) { + CaughtExceptionStack = E->Next; /* Unlink from the stack */ + E->ExceptionDestructor(E); /* Release memory for the exception */ + } + } + + /* __llvm_cxxeh_rethrow - This function turns the top-level caught exception + * into an uncaught exception, in preparation for an llvm.unwind, which should + * follow immediately after the call to this function. This function must be + * prepared to deal with foreign exceptions. + */ + void __llvm_cxxeh_rethrow(void) { + llvm_exception *E = CaughtExceptionStack; + if (E == 0) { + /* 15.1.8 - If there are no uncaught exceptions being thrown, 'throw;' + * should call terminate. + */ + /* FIXME */assert(0 && "FIXME: this should call E->Terminate!"); + } + + /* Otherwise we have an exception to rethrow. Move it back to the uncaught + * stack. + */ + CaughtExceptionStack = E->Next; + E->Next = UncaughtExceptionStack; + UncaughtExceptionStack = E; + + /* Decrement the number of handlers which are using the exception. */ + --E->HandlerCount; + + /* Return to the caller, which should perform the unwind now. */ + } + Index: llvm/runtime/GCCLibraries/libexception/c++-exception.h diff -c /dev/null llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.1 *** /dev/null Mon Aug 25 17:35:47 2003 --- llvm/runtime/GCCLibraries/libexception/c++-exception.h Mon Aug 25 17:35:36 2003 *************** *** 0 **** --- 1,62 ---- + //===- c++-exception.h - C++ Specific exception Handling --------*- C++ -*-===// + // + // This file defines the data structures and API used by the C++ exception + // handling runtime library. + // + //===----------------------------------------------------------------------===// + + #ifndef CXX_EXCEPTION_H + #define CXX_EXCEPTION_H + + #include "exception.h" + #include + + typedef struct llvm_cxx_exception { + /* TypeInfo - A pointer to the C++ std::type_info object for this exception + * class. This is required because the class may not be polymorphic. + */ + const std::type_info *TypeInfo; + + /* ExceptionObjectDestructor - A pointer to the function which destroys the + * object represented by this exception. This is required because the class + * may not be polymorphic. This may be null if there is no cleanup required. + */ + void (*ExceptionObjectDestructor)(void *); + + /* UnexpectedHandler - This contains a pointer to the "unexpected" handler + * which may be registered by the user program with set_unexpected. Calls to + * unexpected which are a result of an exception throw are supposed to use the + * value of the handler at the time of the throw, not the currently set value. + */ + void *UnexpectedHandler; + + /* TerminateHandler - This contains a pointer to the "terminate" handler which + * may be registered by the user program with set_terminate. Calls to + * unexpected which are a result of an exception throw are supposed to use the + * value of the handler at the time of the throw, not the currently set value. + */ + void *TerminateHandler; + + /* BaseException - The language independent portion of the exception state. + * This is at the end of the record so that we can add additional members to + * this structure without breaking binary compatibility. + */ + llvm_exception BaseException; + } llvm_cxx_exception; + + + + extern "C" { + void *__llvm_cxxeh_allocate_exception(unsigned NumBytes); + void __llvm_cxxeh_free_exception(void *ObjectPtr); + void __llvm_cxxeh_throw(void *ObjectPtr, const std::type_info *TypeInfoPtr, + void (*DtorPtr)(void*)); + + void * __llvm_cxxeh_current_uncaught_exception_isa(const std::type_info *Ty); + void *__llvm_cxxeh_begin_catch(void); + void __llvm_cxxeh_end_catch(void); + + void __llvm_cxxeh_rethrow(void); + } + + #endif Index: llvm/runtime/GCCLibraries/libexception/exception.h diff -c /dev/null llvm/runtime/GCCLibraries/libexception/exception.h:1.1 *** /dev/null Mon Aug 25 17:35:47 2003 --- llvm/runtime/GCCLibraries/libexception/exception.h Mon Aug 25 17:35:36 2003 *************** *** 0 **** --- 1,49 ---- + //===- exception.h - Generic language-independent exceptions ----*- C++ -*-===// + // + // This file defines the the shared data structures used by all language + // specific exception handling runtime libraries. + // + //===----------------------------------------------------------------------===// + + #ifndef EXCEPTION_H + #define EXCEPTION_H + + typedef struct llvm_exception { + // ExceptionDestructor - This call-back function is used to destroy the + // current exception, without requiring the caller to know what the concrete + // exception type is. + // + void (*ExceptionDestructor)(struct llvm_exception *); + + // ExceptionType - This field identifies what runtime library this exception + // came from. Currently defined values are: + // 0 - Error + // 1 - longjmp exception (see longjmp-exception.c) + // 2 - C++ exception (see c++-exception.c) + // + unsigned ExceptionType; + + // Next - This points to the next exception in the current stack. + struct llvm_exception *Next; + + // HandlerCount - This is a count of the number of handlers which have + // currently caught this exception. If the handler is caught and this number + // falls to zero, the exception is destroyed. + // + unsigned HandlerCount; + } llvm_exception; + + enum { + ErrorException = 0, + LongjmpException = 1, + CXXException = 2, + }; + + // Language independent exception handling API... + // + extern "C" { + bool __llvm_eh_has_uncaught_exception(void); + void *__llvm_eh_current_uncaught_exception_type(unsigned HandlerType); + } + + #endif From lattner at cs.uiuc.edu Mon Aug 25 17:36:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 25 17:36:02 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/ Message-ID: <200308252235.RAA10544@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/runtime/GCCLibraries/libexception added to the repository --- Diffs of the changes: From lattner at cs.uiuc.edu Mon Aug 25 17:36:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 25 17:36:03 2003 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Function.cpp Verifier.cpp Message-ID: <200308252235.RAA10532@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Function.cpp updated: 1.45 -> 1.46 Verifier.cpp updated: 1.57 -> 1.58 --- Log message: As it turns out, things will be simpler than I first expected. We no longer need any exception handling intrinsics beyond llvm.unwind. (yaay) --- Diffs of the changes: Index: llvm/lib/VMCore/Function.cpp diff -u llvm/lib/VMCore/Function.cpp:1.45 llvm/lib/VMCore/Function.cpp:1.46 --- llvm/lib/VMCore/Function.cpp:1.45 Sun Aug 24 07:24:08 2003 +++ llvm/lib/VMCore/Function.cpp Mon Aug 25 17:35:01 2003 @@ -195,10 +195,6 @@ if (getName() == alpha_intrinsics[i].name) return alpha_intrinsics[i].id; break; - case 'e': - if (getName() == "llvm.exc.getcurrent")return LLVMIntrinsic::exc_getcurrent; - if (getName() == "llvm.exc.setcurrent")return LLVMIntrinsic::exc_setcurrent; - break; case 'l': if (getName() == "llvm.longjmp") return LLVMIntrinsic::longjmp; break; Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.57 llvm/lib/VMCore/Verifier.cpp:1.58 --- llvm/lib/VMCore/Verifier.cpp:1.57 Sun Aug 24 07:24:08 2003 +++ llvm/lib/VMCore/Verifier.cpp Mon Aug 25 17:35:01 2003 @@ -523,8 +523,6 @@ case LLVMIntrinsic::va_copy: NumArgs = 2; break; case LLVMIntrinsic::unwind: NumArgs = 0; break; - case LLVMIntrinsic::exc_setcurrent: NumArgs = 1; break; - case LLVMIntrinsic::exc_getcurrent: NumArgs = 0; break; case LLVMIntrinsic::setjmp: NumArgs = 1; break; case LLVMIntrinsic::longjmp: NumArgs = 2; break; From lattner at cs.uiuc.edu Mon Aug 25 17:36:04 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 25 17:36:04 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Intrinsics.h Message-ID: <200308252235.RAA10521@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Intrinsics.h updated: 1.8 -> 1.9 --- Log message: As it turns out, things will be simpler than I first expected. We no longer need any exception handling intrinsics beyond llvm.unwind. (yaay) --- Diffs of the changes: Index: llvm/include/llvm/Intrinsics.h diff -u llvm/include/llvm/Intrinsics.h:1.8 llvm/include/llvm/Intrinsics.h:1.9 --- llvm/include/llvm/Intrinsics.h:1.8 Sun Aug 24 07:24:03 2003 +++ llvm/include/llvm/Intrinsics.h Mon Aug 25 17:34:59 2003 @@ -24,10 +24,6 @@ unwind, // Unwind stack until containing invoke is found - // Exception handling intrinsics... - exc_setcurrent, // Set the current pending exception - exc_getcurrent, // Get the current pending exception - // Setjmp/Longjmp intrinsics... setjmp, // Used to represent a setjmp call in C longjmp, // Used to represent a longjmp call in C From lattner at cs.uiuc.edu Mon Aug 25 17:38:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Aug 25 17:38:02 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/Makefile Message-ID: <200308252237.RAA10693@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: Makefile updated: 1.1 -> 1.2 --- Log message: Remove copy-and-paste gunk --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/Makefile diff -u llvm/runtime/GCCLibraries/libexception/Makefile:1.1 llvm/runtime/GCCLibraries/libexception/Makefile:1.2 --- llvm/runtime/GCCLibraries/libexception/Makefile:1.1 Mon Aug 25 17:35:36 2003 +++ llvm/runtime/GCCLibraries/libexception/Makefile Mon Aug 25 17:37:04 2003 @@ -3,15 +3,4 @@ DONT_BUILD_RELINKED=1 LIBRARYNAME=exception -#Source = crtend.c listend.ll - -###EXPORTED_SYMBOL_LIST = __main,llvm.global_ctors,llvm.global_dtors - include $(LEVEL)/Makefile.common - - -$(LLVMGCCDIR)/bytecode-libs/crtend.o: $(LIBNAME_BC) - @cp $< $@ - -install:: $(LLVMGCCDIR)/bytecode-libs/crtend.o - @rm $(LLVMGCCDIR)/bytecode-libs/libcrtend.bc From tbrethou at cs.uiuc.edu Mon Aug 25 17:43:01 2003 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Mon Aug 25 17:43:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/InstrSched/SchedGraphCommon.cpp InstrScheduling.cpp SchedGraph.cpp SchedGraph.h SchedPriorities.cpp Message-ID: <200308252242.RAA10324@tank.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/InstrSched: SchedGraphCommon.cpp added (r1.1) InstrScheduling.cpp updated: 1.56 -> 1.57 SchedGraph.cpp updated: 1.46 -> 1.47 SchedGraph.h updated: 1.30 -> 1.31 SchedPriorities.cpp updated: 1.25 -> 1.26 --- Log message: First version of SchedGraph common class and refactoring of SchedGraph. --- Diffs of the changes: Index: llvm/lib/CodeGen/InstrSched/SchedGraphCommon.cpp diff -c /dev/null llvm/lib/CodeGen/InstrSched/SchedGraphCommon.cpp:1.1 *** /dev/null Mon Aug 25 17:42:32 2003 --- llvm/lib/CodeGen/InstrSched/SchedGraphCommon.cpp Mon Aug 25 17:42:20 2003 *************** *** 0 **** --- 1,237 ---- + #include "llvm/CodeGen/SchedGraphCommon.h" + #include "Support/STLExtras.h" + + class SchedGraphCommon; + + // + // class SchedGraphEdge + // + + /*ctor*/ + SchedGraphEdge::SchedGraphEdge(SchedGraphNodeCommon* _src, + SchedGraphNodeCommon* _sink, + SchedGraphEdgeDepType _depType, + unsigned int _depOrderType, + int _minDelay) + : src(_src), + sink(_sink), + depType(_depType), + depOrderType(_depOrderType), + minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), + val(NULL) + { + iteDiff=0; + assert(src != sink && "Self-loop in scheduling graph!"); + src->addOutEdge(this); + sink->addInEdge(this); + } + + + /*ctor*/ + SchedGraphEdge::SchedGraphEdge(SchedGraphNodeCommon* _src, + SchedGraphNodeCommon* _sink, + const Value* _val, + unsigned int _depOrderType, + int _minDelay) + : src(_src), + sink(_sink), + depType(ValueDep), + depOrderType(_depOrderType), + minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), + val(_val) + { + iteDiff=0; + assert(src != sink && "Self-loop in scheduling graph!"); + src->addOutEdge(this); + sink->addInEdge(this); + } + + + /*ctor*/ + SchedGraphEdge::SchedGraphEdge(SchedGraphNodeCommon* _src, + SchedGraphNodeCommon* _sink, + unsigned int _regNum, + unsigned int _depOrderType, + int _minDelay) + : src(_src), + sink(_sink), + depType(MachineRegister), + depOrderType(_depOrderType), + minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), + machineRegNum(_regNum) + { + iteDiff=0; + assert(src != sink && "Self-loop in scheduling graph!"); + src->addOutEdge(this); + sink->addInEdge(this); + } + + + /*ctor*/ + SchedGraphEdge::SchedGraphEdge(SchedGraphNodeCommon* _src, + SchedGraphNodeCommon* _sink, + ResourceId _resourceId, + int _minDelay) + : src(_src), + sink(_sink), + depType(MachineResource), + depOrderType(NonDataDep), + minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), + resourceId(_resourceId) + { + iteDiff=0; + assert(src != sink && "Self-loop in scheduling graph!"); + src->addOutEdge(this); + sink->addInEdge(this); + } + + /*dtor*/ + SchedGraphEdge::~SchedGraphEdge() + { + } + + void SchedGraphEdge::dump(int indent) const { + std::cerr << std::string(indent*2, ' ') << *this; + } + + + + /*ctor*/ + + SchedGraphNodeCommon::SchedGraphNodeCommon(unsigned _nodeId) + :ID(_nodeId), + latency(0){ + + } + + /*dtor*/ + SchedGraphNodeCommon::~SchedGraphNodeCommon() + { + // for each node, delete its out-edges + std::for_each(beginOutEdges(), endOutEdges(), + deleter); + } + + + void SchedGraphNodeCommon::dump(int indent) const { + std::cerr << std::string(indent*2, ' ') << *this; + } + + + inline void + SchedGraphNodeCommon::addInEdge(SchedGraphEdge* edge) + { + inEdges.push_back(edge); + } + + + inline void + SchedGraphNodeCommon::addOutEdge(SchedGraphEdge* edge) + { + outEdges.push_back(edge); + } + + inline void + SchedGraphNodeCommon::removeInEdge(const SchedGraphEdge* edge) + { + assert(edge->getSink() == this); + + for (iterator I = beginInEdges(); I != endInEdges(); ++I) + if ((*I) == edge) + { + inEdges.erase(I); + break; + } + } + + inline void + SchedGraphNodeCommon::removeOutEdge(const SchedGraphEdge* edge) + { + assert(edge->getSrc() == this); + + for (iterator I = beginOutEdges(); I != endOutEdges(); ++I) + if ((*I) == edge) + { + outEdges.erase(I); + break; + } + } + + + //class SchedGraphCommon + + /*ctor*/ + SchedGraphCommon::SchedGraphCommon() + { + } + + + /*dtor*/ + SchedGraphCommon::~SchedGraphCommon() + { + + delete graphRoot; + delete graphLeaf; + } + + + void + SchedGraphCommon::eraseIncomingEdges(SchedGraphNodeCommon* node, bool addDummyEdges) + { + // Delete and disconnect all in-edges for the node + for (SchedGraphNodeCommon::iterator I = node->beginInEdges(); + I != node->endInEdges(); ++I) + { + SchedGraphNodeCommon* srcNode = (*I)->getSrc(); + srcNode->removeOutEdge(*I); + delete *I; + + if (addDummyEdges && + srcNode != getRoot() && + srcNode->beginOutEdges() == srcNode->endOutEdges()) + { // srcNode has no more out edges, so add an edge to dummy EXIT node + assert(node != getLeaf() && "Adding edge that was just removed?"); + (void) new SchedGraphEdge(srcNode, getLeaf(), + SchedGraphEdge::CtrlDep, SchedGraphEdge::NonDataDep, 0); + } + } + + node->inEdges.clear(); + } + + void + SchedGraphCommon::eraseOutgoingEdges(SchedGraphNodeCommon* node, bool addDummyEdges) + { + // Delete and disconnect all out-edges for the node + for (SchedGraphNodeCommon::iterator I = node->beginOutEdges(); + I != node->endOutEdges(); ++I) + { + SchedGraphNodeCommon* sinkNode = (*I)->getSink(); + sinkNode->removeInEdge(*I); + delete *I; + + if (addDummyEdges && + sinkNode != getLeaf() && + sinkNode->beginInEdges() == sinkNode->endInEdges()) + { //sinkNode has no more in edges, so add an edge from dummy ENTRY node + assert(node != getRoot() && "Adding edge that was just removed?"); + (void) new SchedGraphEdge(getRoot(), sinkNode, + SchedGraphEdge::CtrlDep, SchedGraphEdge::NonDataDep, 0); + } + } + + node->outEdges.clear(); + } + + void + SchedGraphCommon::eraseIncidentEdges(SchedGraphNodeCommon* node, bool addDummyEdges) + { + this->eraseIncomingEdges(node, addDummyEdges); + this->eraseOutgoingEdges(node, addDummyEdges); + } + + std::ostream &operator<<(std::ostream &os, const SchedGraphNodeCommon& node) + { + + return os; + } Index: llvm/lib/CodeGen/InstrSched/InstrScheduling.cpp diff -u llvm/lib/CodeGen/InstrSched/InstrScheduling.cpp:1.56 llvm/lib/CodeGen/InstrSched/InstrScheduling.cpp:1.57 --- llvm/lib/CodeGen/InstrSched/InstrScheduling.cpp:1.56 Fri Aug 15 00:20:06 2003 +++ llvm/lib/CodeGen/InstrSched/InstrScheduling.cpp Mon Aug 25 17:42:20 2003 @@ -1047,8 +1047,8 @@ for (SchedGraphNode::const_iterator EI = node->beginInEdges(); EI != node->endInEdges(); ++EI) - if (! (*EI)->getSrc()->isDummyNode() - && mii.isLoad((*EI)->getSrc()->getOpCode()) + if (! ((SchedGraphNode*)(*EI)->getSrc())->isDummyNode() + && mii.isLoad(((SchedGraphNode*)(*EI)->getSrc())->getOpCode()) && (*EI)->getDepType() == SchedGraphEdge::CtrlDep) return false; @@ -1065,7 +1065,7 @@ bool onlyCDEdgeToBranch = true; for (SchedGraphNode::const_iterator OEI = node->beginOutEdges(); OEI != node->endOutEdges(); ++OEI) - if (! (*OEI)->getSink()->isDummyNode() + if (! ((SchedGraphNode*)(*OEI)->getSink())->isDummyNode() && ((*OEI)->getSink() != brNode || (*OEI)->getDepType() != SchedGraphEdge::CtrlDep)) { Index: llvm/lib/CodeGen/InstrSched/SchedGraph.cpp diff -u llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.46 llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.47 --- llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.46 Tue Jul 1 20:16:01 2003 +++ llvm/lib/CodeGen/InstrSched/SchedGraph.cpp Mon Aug 25 17:42:20 2003 @@ -7,16 +7,21 @@ //===----------------------------------------------------------------------===// #include "SchedGraph.h" -#include "llvm/CodeGen/InstrSelection.h" -#include "llvm/CodeGen/MachineCodeForInstruction.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/Target/TargetRegInfo.h" +#include "llvm/CodeGen/SchedGraphCommon.h" +#include + #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" +#include "Support/STLExtras.h" +#include "llvm/BasicBlock.h" +#include "llvm/CodeGen/MachineCodeForInstruction.h" +#include "llvm/Target/TargetRegInfo.h" #include "llvm/Function.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/InstrSelection.h" #include "llvm/iOther.h" #include "Support/StringExtras.h" -#include "Support/STLExtras.h" + //*********************** Internal Data Structures *************************/ @@ -39,93 +44,6 @@ typedef hash_map::const_iterator const_iterator; }; -// -// class SchedGraphEdge -// - -/*ctor*/ -SchedGraphEdge::SchedGraphEdge(SchedGraphNode* _src, - SchedGraphNode* _sink, - SchedGraphEdgeDepType _depType, - unsigned int _depOrderType, - int _minDelay) - : src(_src), - sink(_sink), - depType(_depType), - depOrderType(_depOrderType), - minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), - val(NULL) -{ - assert(src != sink && "Self-loop in scheduling graph!"); - src->addOutEdge(this); - sink->addInEdge(this); -} - - -/*ctor*/ -SchedGraphEdge::SchedGraphEdge(SchedGraphNode* _src, - SchedGraphNode* _sink, - const Value* _val, - unsigned int _depOrderType, - int _minDelay) - : src(_src), - sink(_sink), - depType(ValueDep), - depOrderType(_depOrderType), - minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), - val(_val) -{ - assert(src != sink && "Self-loop in scheduling graph!"); - src->addOutEdge(this); - sink->addInEdge(this); -} - - -/*ctor*/ -SchedGraphEdge::SchedGraphEdge(SchedGraphNode* _src, - SchedGraphNode* _sink, - unsigned int _regNum, - unsigned int _depOrderType, - int _minDelay) - : src(_src), - sink(_sink), - depType(MachineRegister), - depOrderType(_depOrderType), - minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), - machineRegNum(_regNum) -{ - assert(src != sink && "Self-loop in scheduling graph!"); - src->addOutEdge(this); - sink->addInEdge(this); -} - - -/*ctor*/ -SchedGraphEdge::SchedGraphEdge(SchedGraphNode* _src, - SchedGraphNode* _sink, - ResourceId _resourceId, - int _minDelay) - : src(_src), - sink(_sink), - depType(MachineResource), - depOrderType(NonDataDep), - minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), - resourceId(_resourceId) -{ - assert(src != sink && "Self-loop in scheduling graph!"); - src->addOutEdge(this); - sink->addInEdge(this); -} - -/*dtor*/ -SchedGraphEdge::~SchedGraphEdge() -{ -} - -void SchedGraphEdge::dump(int indent) const { - std::cerr << std::string(indent*2, ' ') << *this; -} - // // class SchedGraphNode @@ -136,11 +54,11 @@ MachineBasicBlock *mbb, int indexInBB, const TargetMachine& Target) - : nodeId(NID), MBB(mbb), minstr(mbb ? (*mbb)[indexInBB] : 0), - origIndexInBB(indexInBB), latency(0) { - if (minstr) + : SchedGraphNodeCommon(NID), origIndexInBB(indexInBB), MBB(mbb), MI(mbb ? (*mbb)[indexInBB] : 0) + { + if (MI) { - MachineOpCode mopCode = minstr->getOpCode(); + MachineOpCode mopCode = MI->getOpCode(); latency = Target.getInstrInfo().hasResultInterlock(mopCode) ? Target.getInstrInfo().minLatency(mopCode) : Target.getInstrInfo().maxLatency(mopCode); @@ -156,51 +74,6 @@ deleter); } -void SchedGraphNode::dump(int indent) const { - std::cerr << std::string(indent*2, ' ') << *this; -} - - -inline void -SchedGraphNode::addInEdge(SchedGraphEdge* edge) -{ - inEdges.push_back(edge); -} - - -inline void -SchedGraphNode::addOutEdge(SchedGraphEdge* edge) -{ - outEdges.push_back(edge); -} - -inline void -SchedGraphNode::removeInEdge(const SchedGraphEdge* edge) -{ - assert(edge->getSink() == this); - - for (iterator I = beginInEdges(); I != endInEdges(); ++I) - if ((*I) == edge) - { - inEdges.erase(I); - break; - } -} - -inline void -SchedGraphNode::removeOutEdge(const SchedGraphEdge* edge) -{ - assert(edge->getSrc() == this); - - for (iterator I = beginOutEdges(); I != endOutEdges(); ++I) - if ((*I) == edge) - { - outEdges.erase(I); - break; - } -} - - // // class SchedGraph // @@ -243,62 +116,6 @@ } -void -SchedGraph::eraseIncomingEdges(SchedGraphNode* node, bool addDummyEdges) -{ - // Delete and disconnect all in-edges for the node - for (SchedGraphNode::iterator I = node->beginInEdges(); - I != node->endInEdges(); ++I) - { - SchedGraphNode* srcNode = (*I)->getSrc(); - srcNode->removeOutEdge(*I); - delete *I; - - if (addDummyEdges && - srcNode != getRoot() && - srcNode->beginOutEdges() == srcNode->endOutEdges()) - { - // srcNode has no more out edges, so add an edge to dummy EXIT node - assert(node != getLeaf() && "Adding edge that was just removed?"); - (void) new SchedGraphEdge(srcNode, getLeaf(), - SchedGraphEdge::CtrlDep, SchedGraphEdge::NonDataDep, 0); - } - } - - node->inEdges.clear(); -} - -void -SchedGraph::eraseOutgoingEdges(SchedGraphNode* node, bool addDummyEdges) -{ - // Delete and disconnect all out-edges for the node - for (SchedGraphNode::iterator I = node->beginOutEdges(); - I != node->endOutEdges(); ++I) - { - SchedGraphNode* sinkNode = (*I)->getSink(); - sinkNode->removeInEdge(*I); - delete *I; - - if (addDummyEdges && - sinkNode != getLeaf() && - sinkNode->beginInEdges() == sinkNode->endInEdges()) - { //sinkNode has no more in edges, so add an edge from dummy ENTRY node - assert(node != getRoot() && "Adding edge that was just removed?"); - (void) new SchedGraphEdge(getRoot(), sinkNode, - SchedGraphEdge::CtrlDep, SchedGraphEdge::NonDataDep, 0); - } - } - - node->outEdges.clear(); -} - -void -SchedGraph::eraseIncidentEdges(SchedGraphNode* node, bool addDummyEdges) -{ - this->eraseIncomingEdges(node, addDummyEdges); - this->eraseOutgoingEdges(node, addDummyEdges); -} - void SchedGraph::addDummyEdges() @@ -697,10 +514,10 @@ // Collect the register references and value defs. for explicit operands // - const MachineInstr& minstr = *node->getMachineInstr(); - for (int i=0, numOps = (int) minstr.getNumOperands(); i < numOps; i++) + const MachineInstr& MI = *node->getMachineInstr(); + for (int i=0, numOps = (int) MI.getNumOperands(); i < numOps; i++) { - const MachineOperand& mop = minstr.getOperand(i); + const MachineOperand& mop = MI.getOperand(i); // if this references a register other than the hardwired // "zero" register, record the reference. @@ -728,8 +545,8 @@ } // ignore all other non-def operands - if (!minstr.getOperand(i).opIsDefOnly() && - !minstr.getOperand(i).opIsDefAndUse()) + if (!MI.getOperand(i).opIsDefOnly() && + !MI.getOperand(i).opIsDefAndUse()) continue; // We must be defining a value. @@ -745,21 +562,21 @@ // Collect value defs. for implicit operands. They may have allocated // physical registers also. // - for (unsigned i=0, N = minstr.getNumImplicitRefs(); i != N; ++i) + for (unsigned i=0, N = MI.getNumImplicitRefs(); i != N; ++i) { - const MachineOperand& mop = minstr.getImplicitOp(i); + const MachineOperand& mop = MI.getImplicitOp(i); if (mop.hasAllocatedReg()) { int regNum = mop.getAllocatedRegNum(); if (regNum != target.getRegInfo().getZeroRegNum()) regToRefVecMap[mop.getAllocatedRegNum()] - .push_back(std::make_pair(node, i + minstr.getNumOperands())); + .push_back(std::make_pair(node, i + MI.getNumOperands())); continue; // nothing more to do } if (mop.opIsDefOnly() || mop.opIsDefAndUse()) { - assert(minstr.getImplicitRef(i) != NULL && "Null value being defined?"); - valueToDefVecMap[minstr.getImplicitRef(i)].push_back(std::make_pair(node, + assert(MI.getImplicitRef(i) != NULL && "Null value being defined?"); + valueToDefVecMap[MI.getImplicitRef(i)].push_back(std::make_pair(node, -i)); } } @@ -885,9 +702,9 @@ /*ctor*/ SchedGraphSet::SchedGraphSet(const Function* _function, const TargetMachine& target) : - method(_function) + function(_function) { - buildGraphsForMethod(method, target); + buildGraphsForMethod(function, target); } @@ -903,13 +720,13 @@ void SchedGraphSet::dump() const { - std::cerr << "======== Sched graphs for function `" << method->getName() + std::cerr << "======== Sched graphs for function `" << function->getName() << "' ========\n\n"; for (const_iterator I=begin(); I != end(); ++I) (*I)->dump(); - std::cerr << "\n====== End graphs for function `" << method->getName() + std::cerr << "\n====== End graphs for function `" << function->getName() << "' ========\n\n"; } @@ -946,7 +763,7 @@ std::ostream &operator<<(std::ostream &os, const SchedGraphNode& node) { os << std::string(8, ' ') - << "Node " << node.nodeId << " : " + << "Node " << node.ID << " : " << "latency = " << node.latency << "\n" << std::string(12, ' '); if (node.getMachineInstr() == NULL) Index: llvm/lib/CodeGen/InstrSched/SchedGraph.h diff -u llvm/lib/CodeGen/InstrSched/SchedGraph.h:1.30 llvm/lib/CodeGen/InstrSched/SchedGraph.h:1.31 --- llvm/lib/CodeGen/InstrSched/SchedGraph.h:1.30 Sat Jul 26 18:22:19 2003 +++ llvm/lib/CodeGen/InstrSched/SchedGraph.h Mon Aug 25 17:42:20 2003 @@ -17,264 +17,80 @@ #include "llvm/CodeGen/MachineInstr.h" #include "Support/GraphTraits.h" #include "Support/hash_map" +#include "llvm/Transforms/Scalar.h" +#include "llvm/CodeGen/SchedGraphCommon.h" -class Value; -class Instruction; -class TerminatorInst; -class BasicBlock; -class Function; -class TargetMachine; -class SchedGraphEdge; -class SchedGraphNode; -class SchedGraph; class RegToRefVecMap; class ValueToDefVecMap; class RefVec; -class MachineInstr; -class MachineBasicBlock; +class SchedGraphNode : public SchedGraphNodeCommon { -/******************** Exported Data Types and Constants ********************/ - -typedef int ResourceId; -const ResourceId InvalidRID = -1; -const ResourceId MachineCCRegsRID = -2; // use +ve numbers for actual regs -const ResourceId MachineIntRegsRID = -3; // use +ve numbers for actual regs -const ResourceId MachineFPRegsRID = -4; // use +ve numbers for actual regs - - -//*********************** Public Class Declarations ************************/ - -class SchedGraphEdge { - SchedGraphEdge(const SchedGraphEdge &); // DO NOT IMPLEMENT - void operator=(const SchedGraphEdge &); // DO NOT IMPLEMENT -public: - enum SchedGraphEdgeDepType { - CtrlDep, MemoryDep, ValueDep, MachineRegister, MachineResource - }; - enum DataDepOrderType { - TrueDep = 0x1, AntiDep=0x2, OutputDep=0x4, NonDataDep=0x8 - }; - -private: - SchedGraphNode* src; - SchedGraphNode* sink; - SchedGraphEdgeDepType depType; - unsigned int depOrderType; - int minDelay; // cached latency (assumes fixed target arch) - - union { - const Value* val; - int machineRegNum; - ResourceId resourceId; - }; - -public: - // For all constructors, if minDelay is unspecified, minDelay is - // set to _src->getLatency(). - // constructor for CtrlDep or MemoryDep edges, selected by 3rd argument - /*ctor*/ SchedGraphEdge(SchedGraphNode* _src, - SchedGraphNode* _sink, - SchedGraphEdgeDepType _depType, - unsigned int _depOrderType, - int _minDelay = -1); - - // constructor for explicit value dependence (may be true/anti/output) - /*ctor*/ SchedGraphEdge(SchedGraphNode* _src, - SchedGraphNode* _sink, - const Value* _val, - unsigned int _depOrderType, - int _minDelay = -1); - - // constructor for machine register dependence - /*ctor*/ SchedGraphEdge(SchedGraphNode* _src, - SchedGraphNode* _sink, - unsigned int _regNum, - unsigned int _depOrderType, - int _minDelay = -1); - - // constructor for any other machine resource dependences. - // DataDepOrderType is always NonDataDep. It it not an argument to - // avoid overloading ambiguity with previous constructor. - /*ctor*/ SchedGraphEdge(SchedGraphNode* _src, - SchedGraphNode* _sink, - ResourceId _resourceId, - int _minDelay = -1); - - /*dtor*/ ~SchedGraphEdge(); - - SchedGraphNode* getSrc () const { return src; } - SchedGraphNode* getSink () const { return sink; } - int getMinDelay () const { return minDelay; } - SchedGraphEdgeDepType getDepType () const { return depType; } - - const Value* getValue () const { - assert(depType == ValueDep); return val; - } - int getMachineReg () const { - assert(depType == MachineRegister); return machineRegNum; - } - int getResourceId () const { - assert(depType == MachineResource); return resourceId; - } - -public: - // - // Debugging support - // - friend std::ostream& operator<<(std::ostream& os, const SchedGraphEdge& edge); - - void dump (int indent=0) const; - -private: - // disable default ctor - /*ctor*/ SchedGraphEdge(); // DO NOT IMPLEMENT -}; + int origIndexInBB; // original position of machine instr in BB + MachineBasicBlock *MBB; + const MachineInstr *MI; + SchedGraphNode (unsigned nodeId, MachineBasicBlock *mbb, + int indexInBB, const TargetMachine& Target); + ~SchedGraphNode (); -class SchedGraphNode { - unsigned nodeId; - MachineBasicBlock *MBB; - const MachineInstr* minstr; - std::vector inEdges; - std::vector outEdges; - int origIndexInBB; // original position of machine instr in BB - int latency; + friend class SchedGraph; // give access for ctor and dtor + friend class SchedGraphEdge; // give access for adding edges - SchedGraphNode(const SchedGraphNode &); // DO NOT IMPLEMENT - void operator=(const SchedGraphNode &); // DO NOT IMPLEMENT public: - typedef std::vector:: iterator iterator; - typedef std::vector::const_iterator const_iterator; - typedef std::vector:: reverse_iterator reverse_iterator; - typedef std::vector::const_reverse_iterator const_reverse_iterator; - -public: - // // Accessor methods - // - unsigned getNodeId () const { return nodeId; } - const MachineInstr* getMachineInstr () const { return minstr; } - const MachineOpCode getOpCode () const { return minstr->getOpCode(); } - int getLatency () const { return latency; } - unsigned getNumInEdges () const { return inEdges.size(); } - unsigned getNumOutEdges () const { return outEdges.size(); } - bool isDummyNode () const { return (minstr == NULL); } + const MachineInstr* getMachineInstr () const { return MI; } + const MachineOpCode getOpCode () const { return MI->getOpCode(); } + bool isDummyNode () const { return (MI == NULL); } MachineBasicBlock &getMachineBasicBlock() const { return *MBB; } - int getOrigIndexInBB() const { return origIndexInBB; } - - // - // Iterators - // - iterator beginInEdges () { return inEdges.begin(); } - iterator endInEdges () { return inEdges.end(); } - iterator beginOutEdges () { return outEdges.begin(); } - iterator endOutEdges () { return outEdges.end(); } - - const_iterator beginInEdges () const { return inEdges.begin(); } - const_iterator endInEdges () const { return inEdges.end(); } - const_iterator beginOutEdges () const { return outEdges.begin(); } - const_iterator endOutEdges () const { return outEdges.end(); } - -public: - // - // Debugging support - // - friend std::ostream& operator<<(std::ostream& os, const SchedGraphNode& node); - - void dump (int indent=0) const; - -private: - friend class SchedGraph; // give access for ctor and dtor - friend class SchedGraphEdge; // give access for adding edges - - void addInEdge (SchedGraphEdge* edge); - void addOutEdge (SchedGraphEdge* edge); - - void removeInEdge (const SchedGraphEdge* edge); - void removeOutEdge (const SchedGraphEdge* edge); - - // disable default constructor and provide a ctor for single-block graphs - /*ctor*/ SchedGraphNode(); // DO NOT IMPLEMENT - /*ctor*/ SchedGraphNode (unsigned nodeId, - MachineBasicBlock *mbb, - int indexInBB, - const TargetMachine& Target); - /*dtor*/ ~SchedGraphNode (); -}; - + int getOrigIndexInBB() const { return origIndexInBB; } +}; -class SchedGraph : private hash_map { - MachineBasicBlock &MBB; // basic blocks for this graph - SchedGraphNode* graphRoot; // the root and leaf are not inserted - SchedGraphNode* graphLeaf; // in the hash_map (see getNumNodes()) - - typedef hash_map map_base; - SchedGraph(const SchedGraph &); // DO NOT IMPLEMENT - void operator=(const SchedGraph &); // DO NOT IMPLEMENT -public: - using map_base::iterator; - using map_base::const_iterator; +class SchedGraph : public SchedGraphCommon { + MachineBasicBlock &MBB; + hash_map GraphMap; public: - // - // Accessor methods - // - MachineBasicBlock &getBasicBlock() const { return MBB; } - unsigned getNumNodes() const { return size()+2; } - SchedGraphNode* getRoot() const { return graphRoot; } - SchedGraphNode* getLeaf() const { return graphLeaf; } - - SchedGraphNode* getGraphNodeForInstr(const MachineInstr* minstr) const { - const_iterator onePair = this->find(minstr); - return (onePair != this->end())? (*onePair).second : NULL; + typedef hash_map::const_iterator iterator; + typedef hash_map::const_iterator const_iterator; + + MachineBasicBlock& getBasicBlock() const{return MBB;} + const unsigned int getNumNodes() const { return GraphMap.size()+2; } + SchedGraphNode* getGraphNodeForInstr(const MachineInstr* MI) const { + const_iterator onePair = find(MI); + return (onePair != end())? onePair->second : NULL; } - // - // Delete nodes or edges from the graph. - // - void eraseNode (SchedGraphNode* node); - - void eraseIncomingEdges (SchedGraphNode* node, - bool addDummyEdges = true); - - void eraseOutgoingEdges (SchedGraphNode* node, - bool addDummyEdges = true); - - void eraseIncidentEdges (SchedGraphNode* node, - bool addDummyEdges = true); + // Debugging support + void dump () const; - // - // Unordered iterators. - // Return values is pair. - // - using map_base::begin; - using map_base::end; +protected: + SchedGraph(MachineBasicBlock& mbb, const TargetMachine& TM); + ~SchedGraph(); - // - // Ordered iterators. + // Unordered iterators. // Return values is pair. // - // void postord_init(); - // postorder_iterator postord_begin(); - // postorder_iterator postord_end(); - // const_postorder_iterator postord_begin() const; - // const_postorder_iterator postord_end() const; + hash_map::const_iterator begin() const { + return GraphMap.begin(); + } + hash_map::const_iterator end() const { + return GraphMap.end(); + } + + unsigned size() { return GraphMap.size(); } + iterator find(const MachineInstr *MI) const { return GraphMap.find(MI); } - // - // Debugging support - // - void dump () const; + SchedGraphNode *&operator[](const MachineInstr *MI) { + return GraphMap[MI]; + } private: friend class SchedGraphSet; // give access to ctor - // disable default constructor and provide a ctor for single-block graphs - /*ctor*/ SchedGraph (MachineBasicBlock &bb, - const TargetMachine& target); - /*dtor*/ ~SchedGraph (); + inline void noteGraphNodeForInstr (const MachineInstr* minstr, SchedGraphNode* node) @@ -288,12 +104,13 @@ // void buildGraph (const TargetMachine& target); - void buildNodesForBB (const TargetMachine& target, + void buildNodesForBB (const TargetMachine& target, MachineBasicBlock &MBB, std::vector& memNV, std::vector& callNV, RegToRefVecMap& regToRefVecMap, ValueToDefVecMap& valueToDefVecMap); + void findDefUseInfoAtInstr (const TargetMachine& target, SchedGraphNode* node, @@ -301,6 +118,7 @@ std::vector& callNV, RegToRefVecMap& regToRefVecMap, ValueToDefVecMap& valueToDefVecMap); + void addEdgesForInstruction(const MachineInstr& minstr, const ValueToDefVecMap& valueToDefVecMap, @@ -309,12 +127,15 @@ void addCDEdges (const TerminatorInst* term, const TargetMachine& target); - void addMemEdges (const std::vector& memNV, + void addMemEdges (const std::vector& memNod, const TargetMachine& target); + void addCallCCEdges (const std::vector& memNod, + MachineBasicBlock& bbMvec, + const TargetMachine& target); void addCallDepEdges (const std::vector& callNV, const TargetMachine& target); - + void addMachineRegEdges (RegToRefVecMap& regToRefVecMap, const TargetMachine& target); @@ -324,44 +145,41 @@ bool refNodeIsDef, bool refNodeIsDefAndUse, const TargetMachine& target); - - void addDummyEdges (); + void addDummyEdges(); + }; -class SchedGraphSet : private std::vector { -private: - const Function* method; - SchedGraphSet(const SchedGraphSet&); // DO NOT IMPLEMENT - void operator=(const SchedGraphSet&); // DO NOT IMPLEMENT -public: - typedef std::vector baseVector; - using baseVector::iterator; - using baseVector::const_iterator; - +class SchedGraphSet { + const Function* function; + std::vector Graphs; + + // Graph builder + void buildGraphsForMethod (const Function *F, const TargetMachine& target); + + inline void addGraph(SchedGraph* graph) { + assert(graph != NULL); + Graphs.push_back(graph); + } + public: - SchedGraphSet(const Function *F, const TargetMachine &TM); + SchedGraphSet(const Function * function, const TargetMachine& target); ~SchedGraphSet(); - // Iterators - using baseVector::begin; - using baseVector::end; - + //iterators + typedef std::vector::const_iterator iterator; + typedef std::vector::const_iterator const_iterator; + + std::vector::const_iterator begin() const { return Graphs.begin(); } + std::vector::const_iterator end() const { return Graphs.end(); } + // Debugging support void dump() const; - -private: - inline void addGraph(SchedGraph* graph) { - assert(graph != NULL); - this->push_back(graph); - } - - // Graph builder - void buildGraphsForMethod(const Function *F, const TargetMachine &TM); }; + //********************** Sched Graph Iterators *****************************/ // Ok to make it a template because it shd get instantiated at most twice: @@ -381,7 +199,7 @@ inline bool operator!=(const _Self& x) const { return !operator==(x); } // operator*() differs for pred or succ iterator - inline _NodeType* operator*() const { return (*oi)->getSrc(); } + inline _NodeType* operator*() const { return (_NodeType*)(*oi)->getSrc(); } inline _NodeType* operator->() const { return operator*(); } inline _EdgeType* getEdge() const { return *(oi); } @@ -409,7 +227,7 @@ inline bool operator==(const _Self& x) const { return oi == x.oi; } inline bool operator!=(const _Self& x) const { return !operator==(x); } - inline _NodeType* operator*() const { return (*oi)->getSink(); } + inline _NodeType* operator*() const { return (_NodeType*)(*oi)->getSink(); } inline _NodeType* operator->() const { return operator*(); } inline _EdgeType* getEdge() const { return *(oi); } @@ -477,7 +295,7 @@ typedef SchedGraphNode NodeType; typedef sg_succ_iterator ChildIteratorType; - static inline NodeType *getEntryNode(SchedGraph *SG) { return SG->getRoot(); } + static inline NodeType *getEntryNode(SchedGraph *SG) { return (NodeType*)SG->getRoot(); } static inline ChildIteratorType child_begin(NodeType *N) { return succ_begin(N); } @@ -491,7 +309,7 @@ typedef sg_succ_const_iterator ChildIteratorType; static inline NodeType *getEntryNode(const SchedGraph *SG) { - return SG->getRoot(); + return (NodeType*)SG->getRoot(); } static inline ChildIteratorType child_begin(NodeType *N) { return succ_begin(N); Index: llvm/lib/CodeGen/InstrSched/SchedPriorities.cpp diff -u llvm/lib/CodeGen/InstrSched/SchedPriorities.cpp:1.25 llvm/lib/CodeGen/InstrSched/SchedPriorities.cpp:1.26 --- llvm/lib/CodeGen/InstrSched/SchedPriorities.cpp:1.25 Tue Jan 14 17:05:04 2003 +++ llvm/lib/CodeGen/InstrSched/SchedPriorities.cpp Mon Aug 25 17:42:20 2003 @@ -59,7 +59,7 @@ for (SchedGraphNode::const_iterator E=node->beginOutEdges(); E != node->endOutEdges(); ++E) { - cycles_t sinkDelay = getNodeDelay((*E)->getSink()); + cycles_t sinkDelay = getNodeDelay((SchedGraphNode*)(*E)->getSink()); nodeDelay = std::max(nodeDelay, sinkDelay + (*E)->getMinDelay()); } } @@ -71,7 +71,7 @@ void SchedPriorities::initializeReadyHeap(const SchedGraph* graph) { - const SchedGraphNode* graphRoot = graph->getRoot(); + const SchedGraphNode* graphRoot = (const SchedGraphNode*)graph->getRoot(); assert(graphRoot->getMachineInstr() == NULL && "Expect dummy root"); // Insert immediate successors of dummy root, which are the actual roots @@ -137,7 +137,7 @@ for (SchedGraphNode::const_iterator E=node->beginOutEdges(); E != node->endOutEdges(); ++E) { - cycles_t& etime = getEarliestReadyTimeForNodeRef((*E)->getSink()); + cycles_t& etime = getEarliestReadyTimeForNodeRef((SchedGraphNode*)(*E)->getSink()); etime = std::max(etime, curTime + (*E)->getMinDelay()); } } From tbrethou at cs.uiuc.edu Mon Aug 25 18:13:01 2003 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Mon Aug 25 18:13:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SchedGraphCommon.h Message-ID: <200308252312.SAA19355@tank.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SchedGraphCommon.h added (r1.1) --- Log message: SchedGraphCommon header file. Contains class definition for SchedGraphCommon which is used by SchedGraph and ModuloSchedGraph (coming soon). --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/SchedGraphCommon.h diff -c /dev/null llvm/include/llvm/CodeGen/SchedGraphCommon.h:1.1 *** /dev/null Mon Aug 25 18:12:33 2003 --- llvm/include/llvm/CodeGen/SchedGraphCommon.h Mon Aug 25 18:12:23 2003 *************** *** 0 **** --- 1,215 ---- + //===-- SchedGraphCommon.h - Scheduling Base Graph ---------------*- C++ -*---=// + // + // A common graph class that is based on the SSA graph. It includes + // extra dependencies that are caused by machine resources. + // + //===-------------------------------------------------------------------------=// + + #ifndef LLVM_CODEGEN_SCHEDGRAPHCOMMON_H + #define LLVM_CODEGEN_SCHEDGRAPHCOMMON_H + + #include + #include + #include "llvm/Value.h" + + + class SchedGraphEdge; + class SchedGraphNode; + + /******************** Exported Data Types and Constants ********************/ + + typedef int ResourceId; + const ResourceId InvalidRID = -1; + const ResourceId MachineCCRegsRID = -2; // use +ve numbers for actual regs + const ResourceId MachineIntRegsRID = -3; // use +ve numbers for actual regs + const ResourceId MachineFPRegsRID = -4; // use +ve numbers for actual regs + + //*********************** Public Class Declarations ************************/ + + class SchedGraphNodeCommon { + protected: + unsigned ID; + std::vector inEdges; + std::vector outEdges; + int latency; + + friend std::ostream& operator<<(std::ostream& os, const SchedGraphNode& node); + + public: + typedef std::vector:: iterator iterator; + typedef std::vector::const_iterator const_iterator; + typedef std::vector:: reverse_iterator reverse_iterator; + typedef std::vector::const_reverse_iterator const_reverse_iterator; + + // Accessor methods + unsigned getNodeId () const { return ID; } + int getLatency () const { return latency; } + unsigned getNumInEdges () const { return inEdges.size(); } + unsigned getNumOutEdges () const { return outEdges.size(); } + + + // Iterators + iterator beginInEdges () { return inEdges.begin(); } + iterator endInEdges () { return inEdges.end(); } + iterator beginOutEdges () { return outEdges.begin(); } + iterator endOutEdges () { return outEdges.end(); } + + const_iterator beginInEdges () const { return inEdges.begin(); } + const_iterator endInEdges () const { return inEdges.end(); } + const_iterator beginOutEdges () const { return outEdges.begin(); } + const_iterator endOutEdges () const { return outEdges.end(); } + + + // Debugging support + friend std::ostream& operator<<(std::ostream& os, const SchedGraphNodeCommon& node); + + void dump (int indent=0) const; + + protected: + friend class SchedGraph; + friend class SchedGraphCommon; + friend class SchedGraphEdge; // give access for adding edges + //friend class ModuloSchedGraph; + + void addInEdge (SchedGraphEdge* edge); + void addOutEdge (SchedGraphEdge* edge); + + void removeInEdge (const SchedGraphEdge* edge); + void removeOutEdge (const SchedGraphEdge* edge); + + // disable default constructor and provide a ctor for single-block graphs + SchedGraphNodeCommon(); // DO NOT IMPLEMENT + + SchedGraphNodeCommon(unsigned Id); + + virtual ~SchedGraphNodeCommon(); + }; + + + class SchedGraphEdge { + public: + enum SchedGraphEdgeDepType { + CtrlDep, MemoryDep, ValueDep, MachineRegister, MachineResource + }; + enum DataDepOrderType { + TrueDep = 0x1, AntiDep=0x2, OutputDep=0x4, NonDataDep=0x8 + }; + + protected: + SchedGraphNodeCommon* src; + SchedGraphNodeCommon* sink; + SchedGraphEdgeDepType depType; + unsigned int depOrderType; + int minDelay; // cached latency (assumes fixed target arch) + int iteDiff; + + union { + const Value* val; + int machineRegNum; + ResourceId resourceId; + }; + + public: + // For all constructors, if minDelay is unspecified, minDelay is + // set to _src->getLatency(). + // constructor for CtrlDep or MemoryDep edges, selected by 3rd argument + /*ctor*/ SchedGraphEdge(SchedGraphNodeCommon* _src, + SchedGraphNodeCommon* _sink, + SchedGraphEdgeDepType _depType, + unsigned int _depOrderType, + int _minDelay = -1); + + // constructor for explicit value dependence (may be true/anti/output) + /*ctor*/ SchedGraphEdge(SchedGraphNodeCommon* _src, + SchedGraphNodeCommon* _sink, + const Value* _val, + unsigned int _depOrderType, + int _minDelay = -1); + + // constructor for machine register dependence + /*ctor*/ SchedGraphEdge(SchedGraphNodeCommon* _src, + SchedGraphNodeCommon* _sink, + unsigned int _regNum, + unsigned int _depOrderType, + int _minDelay = -1); + + // constructor for any other machine resource dependences. + // DataDepOrderType is always NonDataDep. It it not an argument to + // avoid overloading ambiguity with previous constructor. + /*ctor*/ SchedGraphEdge(SchedGraphNodeCommon* _src, + SchedGraphNodeCommon* _sink, + ResourceId _resourceId, + int _minDelay = -1); + + /*dtor*/ ~SchedGraphEdge(); + + SchedGraphNodeCommon* getSrc () const { return src; } + SchedGraphNodeCommon* getSink () const { return sink; } + int getMinDelay () const { return minDelay; } + SchedGraphEdgeDepType getDepType () const { return depType; } + + const Value* getValue () const { + assert(depType == ValueDep); return val; + } + int getMachineReg () const { + assert(depType == MachineRegister); return machineRegNum; + } + int getResourceId () const { + assert(depType == MachineResource); return resourceId; + } + void setIteDiff (int _iteDiff) { + iteDiff = _iteDiff; + } + int getIteDiff (){ + return iteDiff; + } + + public: + // + // Debugging support + // + friend std::ostream& operator<<(std::ostream& os, const SchedGraphEdge& edge); + + void dump (int indent=0) const; + + private: + // disable default ctor + /*ctor*/ SchedGraphEdge(); // DO NOT IMPLEMENT + }; + + + class SchedGraphCommon { + + protected: + SchedGraphNodeCommon* graphRoot; // the root and leaf are not inserted + SchedGraphNodeCommon* graphLeaf; // in the hash_map (see getNumNodes()) + + public: + // + // Accessor methods + // + SchedGraphNodeCommon* getRoot() const { return graphRoot; } + SchedGraphNodeCommon* getLeaf() const { return graphLeaf; } + + // + // Delete nodes or edges from the graph. + // + void eraseNode (SchedGraphNodeCommon* node); + + void eraseIncomingEdges (SchedGraphNodeCommon* node, + bool addDummyEdges = true); + + void eraseOutgoingEdges (SchedGraphNodeCommon* node, + bool addDummyEdges = true); + + void eraseIncidentEdges (SchedGraphNodeCommon* node, + bool addDummyEdges = true); + + /*ctor*/ SchedGraphCommon (); + /*dtor*/ ~SchedGraphCommon (); + + }; + + + + #endif From lattner at cs.uiuc.edu Tue Aug 26 18:48:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 26 18:48:01 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/c++-exception.cpp c++-exception.h Message-ID: <200308262347.SAA30663@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: c++-exception.cpp updated: 1.1 -> 1.2 c++-exception.h updated: 1.1 -> 1.2 --- Log message: Add new __llvm_cxxeh_begin_catch_if_isa function, change C -> C++ comments --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/c++-exception.cpp diff -u llvm/runtime/GCCLibraries/libexception/c++-exception.cpp:1.1 llvm/runtime/GCCLibraries/libexception/c++-exception.cpp:1.2 --- llvm/runtime/GCCLibraries/libexception/c++-exception.cpp:1.1 Mon Aug 25 17:35:36 2003 +++ llvm/runtime/GCCLibraries/libexception/c++-exception.cpp Tue Aug 26 18:46:53 2003 @@ -42,9 +42,9 @@ } -/*===----------------------------------------------------------------------===** - * C++ Specific exception handling support... - */ +//===----------------------------------------------------------------------===// +// C++ Specific exception handling support... +// // __llvm_cxxeh_allocate_exception - This function allocates space for the // specified number of bytes, plus a C++ exception object header. @@ -113,8 +113,8 @@ E->TypeInfo = TypeInfoPtr; E->ExceptionObjectDestructor = DtorPtr; - E->UnexpectedHandler = 0; /* FIXME */ - E->TerminateHandler = 0; /* FIXME */ + E->UnexpectedHandler = 0; // FIXME + E->TerminateHandler = 0; // FIXME } // __llvm_cxxeh_current_uncaught_exception_isa - This function checks to see if @@ -126,7 +126,7 @@ const std::type_info *CatchType) { assert(UncaughtExceptionStack && "No uncaught exception!"); if (UncaughtExceptionStack->ExceptionType != CXXException) - return 0; /* If it's not a c++ exception, it doesn't match! */ + return 0; // If it's not a c++ exception, it doesn't match! // If it is a C++ exception, use the type info object stored in the exception // to see if TypeID matches and, if so, to adjust the exception object @@ -156,68 +156,83 @@ } -/* __llvm_cxxeh_begin_catch - This function is called by "exception handlers", - * which transition an exception from being uncaught to being caught. It - * returns a pointer to the exception object portion of the exception. This - * function must work with foreign exceptions. - */ +// __llvm_cxxeh_begin_catch - This function is called by "exception handlers", +// which transition an exception from being uncaught to being caught. It +// returns a pointer to the exception object portion of the exception. This +// function must work with foreign exceptions. +// void *__llvm_cxxeh_begin_catch(void) { llvm_exception *E = UncaughtExceptionStack; assert(UncaughtExceptionStack && "There are no uncaught exceptions!?!?"); - /* The exception is now no longer uncaught... */ + // The exception is now no longer uncaught. UncaughtExceptionStack = E->Next; - /* The exception is now caught... */ + // The exception is now caught. E->Next = CaughtExceptionStack; CaughtExceptionStack = E->Next; - /* Increment the handler count for this exception. */ + // Increment the handler count for this exception. E->HandlerCount++; - - /* Return a pointer to the exception object */ + + // Return a pointer to the raw exception object. return E+1; } -/* __llvm_cxxeh_end_catch - This function decrements the HandlerCount of the - * top-level caught exception, destroying it if this is the last handler for the - * exception. - */ +// __llvm_cxxeh_begin_catch_if_isa - This function checks to see if the current +// uncaught exception is of the specified type. If not, it returns a null +// pointer, otherwise it 'catches' the exception and returns a pointer to the +// object of the specified type. This function does never succeeds with foreign +// exceptions (because they can never be of type CatchType). +// +void *__llvm_cxxeh_begin_catch_if_isa(const std::type_info *CatchType) { + void *ObjPtr = __llvm_cxxeh_current_uncaught_exception_isa(CatchType); + if (!ObjPtr) return 0; + + // begin_catch, meaning that the object is now "caught", not "uncaught" + __llvm_cxxeh_begin_catch(); + return ObjPtr; +} + + +// __llvm_cxxeh_end_catch - This function decrements the HandlerCount of the +// top-level caught exception, destroying it if this is the last handler for the +// exception. +// void __llvm_cxxeh_end_catch(void) { llvm_exception *E = CaughtExceptionStack; assert(E && "There are no caught exceptions!"); - /* If this is the last handler using the exception, destroy it now! */ + // If this is the last handler using the exception, destroy it now! if (--E->HandlerCount == 0) { - CaughtExceptionStack = E->Next; /* Unlink from the stack */ - E->ExceptionDestructor(E); /* Release memory for the exception */ + CaughtExceptionStack = E->Next; // Unlink from the stack + E->ExceptionDestructor(E); // Release memory for the exception } } -/* __llvm_cxxeh_rethrow - This function turns the top-level caught exception - * into an uncaught exception, in preparation for an llvm.unwind, which should - * follow immediately after the call to this function. This function must be - * prepared to deal with foreign exceptions. - */ +// __llvm_cxxeh_rethrow - This function turns the top-level caught exception +// into an uncaught exception, in preparation for an llvm.unwind, which should +// follow immediately after the call to this function. This function must be +// prepared to deal with foreign exceptions. +// void __llvm_cxxeh_rethrow(void) { llvm_exception *E = CaughtExceptionStack; if (E == 0) { - /* 15.1.8 - If there are no uncaught exceptions being thrown, 'throw;' - * should call terminate. - */ - /* FIXME */assert(0 && "FIXME: this should call E->Terminate!"); + // 15.1.8 - If there are no uncaught exceptions being thrown, 'throw;' + // should call terminate. + // + assert(0 && "FIXME: this should call E->Terminate!"); // FIXME! } - /* Otherwise we have an exception to rethrow. Move it back to the uncaught - * stack. - */ + // Otherwise we have an exception to rethrow. Move it back to the uncaught + // stack. CaughtExceptionStack = E->Next; E->Next = UncaughtExceptionStack; UncaughtExceptionStack = E; - /* Decrement the number of handlers which are using the exception. */ + // Decrement the number of handlers which are using the exception. --E->HandlerCount; - /* Return to the caller, which should perform the unwind now. */ + // Return to the caller, which should perform the unwind now. } Index: llvm/runtime/GCCLibraries/libexception/c++-exception.h diff -u llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.1 llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.2 --- llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.1 Mon Aug 25 17:35:36 2003 +++ llvm/runtime/GCCLibraries/libexception/c++-exception.h Tue Aug 26 18:46:53 2003 @@ -54,6 +54,7 @@ void * __llvm_cxxeh_current_uncaught_exception_isa(const std::type_info *Ty); void *__llvm_cxxeh_begin_catch(void); + void *__llvm_cxxeh_begin_catch_if_isa(const std::type_info *CatchType); void __llvm_cxxeh_end_catch(void); void __llvm_cxxeh_rethrow(void); From lattner at cs.uiuc.edu Tue Aug 26 20:06:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 26 20:06:02 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/SCCP/2003-08-26-InvokeHandling.ll Message-ID: <200308270105.UAA32481@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/SCCP: 2003-08-26-InvokeHandling.ll added (r1.1) --- Log message: New testcase --- Diffs of the changes: Index: llvm/test/Regression/Transforms/SCCP/2003-08-26-InvokeHandling.ll diff -c /dev/null llvm/test/Regression/Transforms/SCCP/2003-08-26-InvokeHandling.ll:1.1 *** /dev/null Tue Aug 26 20:05:29 2003 --- llvm/test/Regression/Transforms/SCCP/2003-08-26-InvokeHandling.ll Tue Aug 26 20:05:19 2003 *************** *** 0 **** --- 1,15 ---- + ; The PHI cannot be eliminated from this testcase, SCCP is mishandling invoke's! + ; RUN: as < %s | opt -sccp | dis | grep phi + + declare void %foo() + int %test(bool %cond) { + Entry: + br bool %cond, label %Inv, label %Cont + Inv: + invoke void %foo() to label %Ok except label %Cont + Ok: + br label %Cont + Cont: + %X = phi int [0, %Entry], [1,%Ok], [0, %Inv] + ret int %X + } From lattner at cs.uiuc.edu Tue Aug 26 20:09:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 26 20:09:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/SCCP.cpp Message-ID: <200308270108.UAA00528@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: SCCP.cpp updated: 1.72 -> 1.73 --- Log message: Fix bug: SCCP/2003-08-26-InvokeHandling.ll --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/SCCP.cpp diff -u llvm/lib/Transforms/Scalar/SCCP.cpp:1.72 llvm/lib/Transforms/Scalar/SCCP.cpp:1.73 --- llvm/lib/Transforms/Scalar/SCCP.cpp:1.72 Mon Aug 18 09:33:38 2003 +++ llvm/lib/Transforms/Scalar/SCCP.cpp Tue Aug 26 20:08:35 2003 @@ -192,7 +192,10 @@ void visitLoadInst (Instruction &I) { markOverdefined(&I); } void visitGetElementPtrInst(GetElementPtrInst &I); void visitCallInst (Instruction &I) { markOverdefined(&I); } - void visitInvokeInst (Instruction &I) { markOverdefined(&I); } + void visitInvokeInst (TerminatorInst &I) { + markOverdefined(&I); + visitTerminatorInst(I); + } void visitAllocationInst(Instruction &I) { markOverdefined(&I); } void visitVarArgInst (Instruction &I) { markOverdefined(&I); } void visitFreeInst (Instruction &I) { /*returns void*/ } From tbrethou at niobe.cs.uiuc.edu Tue Aug 26 21:44:01 2003 From: tbrethou at niobe.cs.uiuc.edu (Tanya Brethour) Date: Tue Aug 26 21:44:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/InstrSched/SchedGraph.cpp SchedGraph.h SchedGraphCommon.cpp Message-ID: <200308270243.h7R2h9e10148@niobe.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/InstrSched: SchedGraph.cpp updated: 1.47 -> 1.48 SchedGraph.h updated: 1.31 -> 1.32 SchedGraphCommon.cpp updated: 1.1 -> 1.2 --- Log message: (null) --- Diffs of the changes: Index: llvm/lib/CodeGen/InstrSched/SchedGraph.cpp diff -u llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.47 llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.48 --- llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.47 Mon Aug 25 17:42:20 2003 +++ llvm/lib/CodeGen/InstrSched/SchedGraph.cpp Tue Aug 26 21:42:58 2003 @@ -7,21 +7,14 @@ //===----------------------------------------------------------------------===// #include "SchedGraph.h" -#include "llvm/CodeGen/SchedGraphCommon.h" -#include - -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "Support/STLExtras.h" -#include "llvm/BasicBlock.h" -#include "llvm/CodeGen/MachineCodeForInstruction.h" -#include "llvm/Target/TargetRegInfo.h" #include "llvm/Function.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/InstrSelection.h" #include "llvm/iOther.h" -#include "Support/StringExtras.h" - +#include "llvm/CodeGen/MachineCodeForInstruction.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegInfo.h" +#include "Support/STLExtras.h" //*********************** Internal Data Structures *************************/ @@ -49,26 +42,19 @@ // class SchedGraphNode // -/*ctor*/ -SchedGraphNode::SchedGraphNode(unsigned NID, - MachineBasicBlock *mbb, - int indexInBB, - const TargetMachine& Target) - : SchedGraphNodeCommon(NID), origIndexInBB(indexInBB), MBB(mbb), MI(mbb ? (*mbb)[indexInBB] : 0) - { - if (MI) - { - MachineOpCode mopCode = MI->getOpCode(); - latency = Target.getInstrInfo().hasResultInterlock(mopCode) - ? Target.getInstrInfo().minLatency(mopCode) - : Target.getInstrInfo().maxLatency(mopCode); - } +SchedGraphNode::SchedGraphNode(unsigned NID, MachineBasicBlock *mbb, + int indexInBB, const TargetMachine& Target) + : SchedGraphNodeCommon(NID), origIndexInBB(indexInBB), MBB(mbb), + MI(mbb ? (*mbb)[indexInBB] : 0) { + if (MI) { + MachineOpCode mopCode = MI->getOpCode(); + latency = Target.getInstrInfo().hasResultInterlock(mopCode) + ? Target.getInstrInfo().minLatency(mopCode) + : Target.getInstrInfo().maxLatency(mopCode); + } } - -/*dtor*/ -SchedGraphNode::~SchedGraphNode() -{ +SchedGraphNode::~SchedGraphNode() { // for each node, delete its out-edges std::for_each(beginOutEdges(), endOutEdges(), deleter); @@ -77,28 +63,19 @@ // // class SchedGraph // - - -/*ctor*/ SchedGraph::SchedGraph(MachineBasicBlock &mbb, const TargetMachine& target) : MBB(mbb) { buildGraph(target); } - -/*dtor*/ -SchedGraph::~SchedGraph() -{ +SchedGraph::~SchedGraph() { for (const_iterator I = begin(); I != end(); ++I) delete I->second; delete graphRoot; delete graphLeaf; } - -void -SchedGraph::dump() const -{ +void SchedGraph::dump() const { std::cerr << " Sched Graph for Basic Block: "; std::cerr << MBB.getBasicBlock()->getName() << " (" << MBB.getBasicBlock() << ")"; @@ -117,13 +94,10 @@ -void -SchedGraph::addDummyEdges() -{ +void SchedGraph::addDummyEdges() { assert(graphRoot->outEdges.size() == 0); - for (const_iterator I=begin(); I != end(); ++I) - { + for (const_iterator I=begin(); I != end(); ++I) { SchedGraphNode* node = (*I).second; assert(node != graphRoot && node != graphLeaf); if (node->beginInEdges() == node->endInEdges()) @@ -136,10 +110,8 @@ } -void -SchedGraph::addCDEdges(const TerminatorInst* term, - const TargetMachine& target) -{ +void SchedGraph::addCDEdges(const TerminatorInst* term, + const TargetMachine& target) { const TargetInstrInfo& mii = target.getInstrInfo(); MachineCodeForInstruction &termMvec = MachineCodeForInstruction::get(term); @@ -153,22 +125,20 @@ "No branch instructions for terminator? Ok, but weird!"); if (first == termMvec.size()) return; - + SchedGraphNode* firstBrNode = getGraphNodeForInstr(termMvec[first]); - + // Add CD edges from each instruction in the sequence to the // *last preceding* branch instr. in the sequence // Use a latency of 0 because we only need to prevent out-of-order issue. // - for (unsigned i = termMvec.size(); i > first+1; --i) - { + for (unsigned i = termMvec.size(); i > first+1; --i) { SchedGraphNode* toNode = getGraphNodeForInstr(termMvec[i-1]); assert(toNode && "No node for instr generated for branch/ret?"); - + for (unsigned j = i-1; j != 0; --j) if (mii.isBranch(termMvec[j-1]->getOpCode()) || - mii.isReturn(termMvec[j-1]->getOpCode())) - { + mii.isReturn(termMvec[j-1]->getOpCode())) { SchedGraphNode* brNode = getGraphNodeForInstr(termMvec[j-1]); assert(brNode && "No node for instr generated for branch/ret?"); (void) new SchedGraphEdge(brNode, toNode, SchedGraphEdge::CtrlDep, @@ -180,8 +150,7 @@ // Add CD edges from each instruction preceding the first branch // to the first branch. Use a latency of 0 as above. // - for (unsigned i = first; i != 0; --i) - { + for (unsigned i = first; i != 0; --i) { SchedGraphNode* fromNode = getGraphNodeForInstr(termMvec[i-1]); assert(fromNode && "No node for instr generated for branch?"); (void) new SchedGraphEdge(fromNode, firstBrNode, SchedGraphEdge::CtrlDep, @@ -191,15 +160,14 @@ // Now add CD edges to the first branch instruction in the sequence from // all preceding instructions in the basic block. Use 0 latency again. // - for (unsigned i=0, N=MBB.size(); i < N; i++) - { + for (unsigned i=0, N=MBB.size(); i < N; i++) { if (MBB[i] == termMvec[first]) // reached the first branch break; - + SchedGraphNode* fromNode = this->getGraphNodeForInstr(MBB[i]); if (fromNode == NULL) continue; // dummy instruction, e.g., PHI - + (void) new SchedGraphEdge(fromNode, firstBrNode, SchedGraphEdge::CtrlDep, SchedGraphEdge::NonDataDep, 0); @@ -211,8 +179,7 @@ unsigned d = mii.getNumDelaySlots(MBB[i]->getOpCode()); assert(i+d < N && "Insufficient delay slots for instruction?"); - for (unsigned j=1; j <= d; j++) - { + for (unsigned j=1; j <= d; j++) { SchedGraphNode* toNode = this->getGraphNodeForInstr(MBB[i+j]); assert(toNode && "No node for machine instr in delay slot?"); (void) new SchedGraphEdge(fromNode, toNode, @@ -228,15 +195,15 @@ static const unsigned int SG_DepOrderArray[][3] = { { SchedGraphEdge::NonDataDep, - SchedGraphEdge::AntiDep, - SchedGraphEdge::AntiDep }, + SchedGraphEdge::AntiDep, + SchedGraphEdge::AntiDep }, { SchedGraphEdge::TrueDep, - SchedGraphEdge::OutputDep, - SchedGraphEdge::TrueDep | SchedGraphEdge::OutputDep }, + SchedGraphEdge::OutputDep, + SchedGraphEdge::TrueDep | SchedGraphEdge::OutputDep }, { SchedGraphEdge::TrueDep, - SchedGraphEdge::AntiDep | SchedGraphEdge::OutputDep, - SchedGraphEdge::TrueDep | SchedGraphEdge::AntiDep - | SchedGraphEdge::OutputDep } + SchedGraphEdge::AntiDep | SchedGraphEdge::OutputDep, + SchedGraphEdge::TrueDep | SchedGraphEdge::AntiDep + | SchedGraphEdge::OutputDep } }; @@ -245,28 +212,24 @@ // Use latency 1 just to ensure that memory operations are ordered; // latency does not otherwise matter (true dependences enforce that). // -void -SchedGraph::addMemEdges(const std::vector& memNodeVec, - const TargetMachine& target) -{ +void SchedGraph::addMemEdges(const std::vector& memNodeVec, + const TargetMachine& target) { const TargetInstrInfo& mii = target.getInstrInfo(); // Instructions in memNodeVec are in execution order within the basic block, // so simply look at all pairs i]>. // - for (unsigned im=0, NM=memNodeVec.size(); im < NM; im++) - { + for (unsigned im=0, NM=memNodeVec.size(); im < NM; im++) { MachineOpCode fromOpCode = memNodeVec[im]->getOpCode(); int fromType = (mii.isCall(fromOpCode)? SG_CALL_REF : (mii.isLoad(fromOpCode)? SG_LOAD_REF : SG_STORE_REF)); - for (unsigned jm=im+1; jm < NM; jm++) - { + for (unsigned jm=im+1; jm < NM; jm++) { MachineOpCode toOpCode = memNodeVec[jm]->getOpCode(); int toType = (mii.isCall(toOpCode)? SG_CALL_REF : (mii.isLoad(toOpCode)? SG_LOAD_REF : SG_STORE_REF)); - + if (fromType != SG_LOAD_REF || toType != SG_LOAD_REF) (void) new SchedGraphEdge(memNodeVec[im], memNodeVec[jm], SchedGraphEdge::MemoryDep, @@ -281,30 +244,27 @@ // Use a latency of 0 because we only need to prevent out-of-order issue, // like with control dependences. // -void -SchedGraph::addCallDepEdges(const std::vector& callDepNodeVec, - const TargetMachine& target) -{ +void SchedGraph::addCallDepEdges(const std::vector& callDepNodeVec, + const TargetMachine& target) { const TargetInstrInfo& mii = target.getInstrInfo(); // Instructions in memNodeVec are in execution order within the basic block, // so simply look at all pairs i]>. // for (unsigned ic=0, NC=callDepNodeVec.size(); ic < NC; ic++) - if (mii.isCall(callDepNodeVec[ic]->getOpCode())) - { - // Add SG_CALL_REF edges from all preds to this instruction. - for (unsigned jc=0; jc < ic; jc++) - (void) new SchedGraphEdge(callDepNodeVec[jc], callDepNodeVec[ic], - SchedGraphEdge::MachineRegister, - MachineIntRegsRID, 0); - - // And do the same from this instruction to all successors. - for (unsigned jc=ic+1; jc < NC; jc++) - (void) new SchedGraphEdge(callDepNodeVec[ic], callDepNodeVec[jc], - SchedGraphEdge::MachineRegister, - MachineIntRegsRID, 0); - } + if (mii.isCall(callDepNodeVec[ic]->getOpCode())) { + // Add SG_CALL_REF edges from all preds to this instruction. + for (unsigned jc=0; jc < ic; jc++) + (void) new SchedGraphEdge(callDepNodeVec[jc], callDepNodeVec[ic], + SchedGraphEdge::MachineRegister, + MachineIntRegsRID, 0); + + // And do the same from this instruction to all successors. + for (unsigned jc=ic+1; jc < NC; jc++) + (void) new SchedGraphEdge(callDepNodeVec[ic], callDepNodeVec[jc], + SchedGraphEdge::MachineRegister, + MachineIntRegsRID, 0); + } #ifdef CALL_DEP_NODE_VEC_CANNOT_WORK // Find the call instruction nodes and put them in a vector. @@ -320,16 +280,14 @@ // int lastCallNodeIdx = -1; for (unsigned i=0, N=bbMvec.size(); i < N; i++) - if (mii.isCall(bbMvec[i]->getOpCode())) - { + if (mii.isCall(bbMvec[i]->getOpCode())) { ++lastCallNodeIdx; for ( ; lastCallNodeIdx < (int)callNodeVec.size(); ++lastCallNodeIdx) if (callNodeVec[lastCallNodeIdx]->getMachineInstr() == bbMvec[i]) break; assert(lastCallNodeIdx < (int)callNodeVec.size() && "Missed Call?"); } - else if (mii.isCCInstr(bbMvec[i]->getOpCode())) - { + else if (mii.isCCInstr(bbMvec[i]->getOpCode())) { // Add incoming/outgoing edges from/to preceding/later calls SchedGraphNode* ccNode = this->getGraphNodeForInstr(bbMvec[i]); int j=0; @@ -344,19 +302,16 @@ } -void -SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap, - const TargetMachine& target) -{ +void SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap, + const TargetMachine& target) { // This code assumes that two registers with different numbers are // not aliased! // for (RegToRefVecMap::iterator I = regToRefVecMap.begin(); - I != regToRefVecMap.end(); ++I) - { + I != regToRefVecMap.end(); ++I) { int regNum = (*I).first; RefVec& regRefVec = (*I).second; - + // regRefVec is ordered by control flow order in the basic block for (unsigned i=0; i < regRefVec.size(); ++i) { SchedGraphNode* node = regRefVec[i].first; @@ -382,7 +337,7 @@ new SchedGraphEdge(prevNode, node, regNum, SchedGraphEdge::AntiDep); } - + if (prevIsDef) if (!isDef || isDefAndUse) new SchedGraphEdge(prevNode, node, regNum, @@ -398,23 +353,20 @@ // in the basic block. refNode may be a use, a def, or both. // We do not consider other uses because we are not building use-use deps. // -void -SchedGraph::addEdgesForValue(SchedGraphNode* refNode, - const RefVec& defVec, - const Value* defValue, - bool refNodeIsDef, - bool refNodeIsDefAndUse, - const TargetMachine& target) -{ +void SchedGraph::addEdgesForValue(SchedGraphNode* refNode, + const RefVec& defVec, + const Value* defValue, + bool refNodeIsDef, + bool refNodeIsDefAndUse, + const TargetMachine& target) { bool refNodeIsUse = !refNodeIsDef || refNodeIsDefAndUse; // Add true or output dep edges from all def nodes before refNode in BB. // Add anti or output dep edges to all def nodes after refNode. - for (RefVec::const_iterator I=defVec.begin(), E=defVec.end(); I != E; ++I) - { + for (RefVec::const_iterator I=defVec.begin(), E=defVec.end(); I != E; ++I) { if ((*I).first == refNode) continue; // Dont add any self-loops - + if ((*I).first->getOrigIndexInBB() < refNode->getOrigIndexInBB()) { // (*).first is before refNode if (refNodeIsDef) @@ -436,25 +388,20 @@ } -void -SchedGraph::addEdgesForInstruction(const MachineInstr& MI, - const ValueToDefVecMap& valueToDefVecMap, - const TargetMachine& target) -{ +void SchedGraph::addEdgesForInstruction(const MachineInstr& MI, + const ValueToDefVecMap& valueToDefVecMap, + const TargetMachine& target) { SchedGraphNode* node = getGraphNodeForInstr(&MI); if (node == NULL) return; // Add edges for all operands of the machine instruction. // - for (unsigned i = 0, numOps = MI.getNumOperands(); i != numOps; ++i) - { - switch (MI.getOperand(i).getType()) - { + for (unsigned i = 0, numOps = MI.getNumOperands(); i != numOps; ++i) { + switch (MI.getOperand(i).getType()) { case MachineOperand::MO_VirtualRegister: case MachineOperand::MO_CCRegister: - if (const Value* srcI = MI.getOperand(i).getVRegValue()) - { + if (const Value* srcI = MI.getOperand(i).getVRegValue()) { ValueToDefVecMap::const_iterator I = valueToDefVecMap.find(srcI); if (I != valueToDefVecMap.end()) addEdgesForValue(node, I->second, srcI, @@ -462,15 +409,15 @@ MI.getOperand(i).opIsDefAndUse(), target); } break; - + case MachineOperand::MO_MachineRegister: break; - + case MachineOperand::MO_SignExtendedImmed: case MachineOperand::MO_UnextendedImmed: case MachineOperand::MO_PCRelativeDisp: break; // nothing to do for immediate fields - + default: assert(0 && "Unknown machine operand type in SchedGraph builder"); break; @@ -483,8 +430,7 @@ // for (unsigned i=0, N=MI.getNumImplicitRefs(); i < N; ++i) if (MI.getImplicitOp(i).opIsUse() || MI.getImplicitOp(i).opIsDefAndUse()) - if (const Value* srcI = MI.getImplicitRef(i)) - { + if (const Value* srcI = MI.getImplicitRef(i)) { ValueToDefVecMap::const_iterator I = valueToDefVecMap.find(srcI); if (I != valueToDefVecMap.end()) addEdgesForValue(node, I->second, srcI, @@ -494,37 +440,33 @@ } -void -SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target, - SchedGraphNode* node, - std::vector& memNodeVec, - std::vector& callDepNodeVec, - RegToRefVecMap& regToRefVecMap, - ValueToDefVecMap& valueToDefVecMap) -{ +void SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target, + SchedGraphNode* node, + std::vector& memNodeVec, + std::vector& callDepNodeVec, + RegToRefVecMap& regToRefVecMap, + ValueToDefVecMap& valueToDefVecMap) { const TargetInstrInfo& mii = target.getInstrInfo(); MachineOpCode opCode = node->getOpCode(); - + if (mii.isCall(opCode) || mii.isCCInstr(opCode)) callDepNodeVec.push_back(node); - + if (mii.isLoad(opCode) || mii.isStore(opCode) || mii.isCall(opCode)) memNodeVec.push_back(node); // Collect the register references and value defs. for explicit operands // const MachineInstr& MI = *node->getMachineInstr(); - for (int i=0, numOps = (int) MI.getNumOperands(); i < numOps; i++) - { + for (int i=0, numOps = (int) MI.getNumOperands(); i < numOps; i++) { const MachineOperand& mop = MI.getOperand(i); - + // if this references a register other than the hardwired // "zero" register, record the reference. - if (mop.hasAllocatedReg()) - { + if (mop.hasAllocatedReg()) { int regNum = mop.getAllocatedRegNum(); - + // If this is not a dummy zero register, record the reference in order if (regNum != target.getRegInfo().getZeroRegNum()) regToRefVecMap[mop.getAllocatedRegNum()] @@ -554,7 +496,7 @@ mop.getType() == MachineOperand::MO_CCRegister) && "Do not expect any other kind of operand to be defined!"); assert(mop.getVRegValue() != NULL && "Null value being defined?"); - + valueToDefVecMap[mop.getVRegValue()].push_back(std::make_pair(node, i)); } @@ -562,11 +504,9 @@ // Collect value defs. for implicit operands. They may have allocated // physical registers also. // - for (unsigned i=0, N = MI.getNumImplicitRefs(); i != N; ++i) - { + for (unsigned i=0, N = MI.getNumImplicitRefs(); i != N; ++i) { const MachineOperand& mop = MI.getImplicitOp(i); - if (mop.hasAllocatedReg()) - { + if (mop.hasAllocatedReg()) { int regNum = mop.getAllocatedRegNum(); if (regNum != target.getRegInfo().getZeroRegNum()) regToRefVecMap[mop.getAllocatedRegNum()] @@ -583,14 +523,12 @@ } -void -SchedGraph::buildNodesForBB(const TargetMachine& target, - MachineBasicBlock& MBB, - std::vector& memNodeVec, - std::vector& callDepNodeVec, - RegToRefVecMap& regToRefVecMap, - ValueToDefVecMap& valueToDefVecMap) -{ +void SchedGraph::buildNodesForBB(const TargetMachine& target, + MachineBasicBlock& MBB, + std::vector& memNodeVec, + std::vector& callDepNodeVec, + RegToRefVecMap& regToRefVecMap, + ValueToDefVecMap& valueToDefVecMap) { const TargetInstrInfo& mii = target.getInstrInfo(); // Build graph nodes for each VM instruction and gather def/use info. @@ -607,9 +545,7 @@ } -void -SchedGraph::buildGraph(const TargetMachine& target) -{ +void SchedGraph::buildGraph(const TargetMachine& target) { // Use this data structure to note all machine operands that compute // ordinary LLVM values. These must be computed defs (i.e., instructions). // Note that there may be multiple machine instructions that define @@ -698,28 +634,20 @@ // // class SchedGraphSet // - -/*ctor*/ SchedGraphSet::SchedGraphSet(const Function* _function, const TargetMachine& target) : - function(_function) -{ + function(_function) { buildGraphsForMethod(function, target); } - -/*dtor*/ -SchedGraphSet::~SchedGraphSet() -{ +SchedGraphSet::~SchedGraphSet() { // delete all the graphs for(iterator I = begin(), E = end(); I != E; ++I) delete *I; // destructor is a friend } -void -SchedGraphSet::dump() const -{ +void SchedGraphSet::dump() const { std::cerr << "======== Sched graphs for function `" << function->getName() << "' ========\n\n"; @@ -731,54 +659,58 @@ } -void -SchedGraphSet::buildGraphsForMethod(const Function *F, - const TargetMachine& target) -{ +void SchedGraphSet::buildGraphsForMethod(const Function *F, + const TargetMachine& target) { MachineFunction &MF = MachineFunction::get(F); for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) addGraph(new SchedGraph(*I, target)); } -std::ostream &operator<<(std::ostream &os, const SchedGraphEdge& edge) -{ - os << "edge [" << edge.src->getNodeId() << "] -> [" - << edge.sink->getNodeId() << "] : "; - - switch(edge.depType) { - case SchedGraphEdge::CtrlDep: os<< "Control Dep"; break; - case SchedGraphEdge::ValueDep: os<< "Reg Value " << edge.val; break; - case SchedGraphEdge::MemoryDep: os<< "Memory Dep"; break; - case SchedGraphEdge::MachineRegister: os<< "Reg " <getNodeId() << "] -> [" + << sink->getNodeId() << "] : "; + + switch(depType) { + case SchedGraphEdge::CtrlDep: + os<< "Control Dep"; + break; + case SchedGraphEdge::ValueDep: + os<< "Reg Value " << val; + break; + case SchedGraphEdge::MemoryDep: + os<< "Memory Dep"; + break; + case SchedGraphEdge::MachineRegister: + os<< "Reg " << machineRegNum; + break; + case SchedGraphEdge::MachineResource: + os<<"Resource "<< resourceId; + break; + default: + assert(0); + break; } - os << " : delay = " << edge.minDelay << "\n"; - - return os; + os << " : delay = " << minDelay << "\n"; } -std::ostream &operator<<(std::ostream &os, const SchedGraphNode& node) -{ +void SchedGraphNode::print(std::ostream &os) const { os << std::string(8, ' ') - << "Node " << node.ID << " : " - << "latency = " << node.latency << "\n" << std::string(12, ' '); + << "Node " << ID << " : " + << "latency = " << latency << "\n" << std::string(12, ' '); - if (node.getMachineInstr() == NULL) + if (getMachineInstr() == NULL) os << "(Dummy node)\n"; else { - os << *node.getMachineInstr() << "\n" << std::string(12, ' '); - os << node.inEdges.size() << " Incoming Edges:\n"; - for (unsigned i=0, N=node.inEdges.size(); i < N; i++) - os << std::string(16, ' ') << *node.inEdges[i]; + os << *getMachineInstr() << "\n" << std::string(12, ' '); + os << inEdges.size() << " Incoming Edges:\n"; + for (unsigned i=0, N = inEdges.size(); i < N; i++) + os << std::string(16, ' ') << *inEdges[i]; - os << std::string(12, ' ') << node.outEdges.size() + os << std::string(12, ' ') << outEdges.size() << " Outgoing Edges:\n"; - for (unsigned i=0, N=node.outEdges.size(); i < N; i++) - os << std::string(16, ' ') << *node.outEdges[i]; + for (unsigned i=0, N= outEdges.size(); i < N; i++) + os << std::string(16, ' ') << *outEdges[i]; } - - return os; } Index: llvm/lib/CodeGen/InstrSched/SchedGraph.h diff -u llvm/lib/CodeGen/InstrSched/SchedGraph.h:1.31 llvm/lib/CodeGen/InstrSched/SchedGraph.h:1.32 --- llvm/lib/CodeGen/InstrSched/SchedGraph.h:1.31 Mon Aug 25 17:42:20 2003 +++ llvm/lib/CodeGen/InstrSched/SchedGraph.h Tue Aug 26 21:42:58 2003 @@ -14,11 +14,12 @@ #ifndef LLVM_CODEGEN_SCHEDGRAPH_H #define LLVM_CODEGEN_SCHEDGRAPH_H +#include "llvm/CodeGen/SchedGraphCommon.h" #include "llvm/CodeGen/MachineInstr.h" -#include "Support/GraphTraits.h" -#include "Support/hash_map" #include "llvm/Transforms/Scalar.h" -#include "llvm/CodeGen/SchedGraphCommon.h" +#include "Support/hash_map" +#include "Support/GraphTraits.h" + class RegToRefVecMap; class ValueToDefVecMap; @@ -31,21 +32,23 @@ const MachineInstr *MI; - SchedGraphNode (unsigned nodeId, MachineBasicBlock *mbb, - int indexInBB, const TargetMachine& Target); - ~SchedGraphNode (); + SchedGraphNode(unsigned nodeId, MachineBasicBlock *mbb, int indexInBB, + const TargetMachine& Target); + ~SchedGraphNode(); friend class SchedGraph; // give access for ctor and dtor friend class SchedGraphEdge; // give access for adding edges public: + // Accessor methods - const MachineInstr* getMachineInstr () const { return MI; } - const MachineOpCode getOpCode () const { return MI->getOpCode(); } - bool isDummyNode () const { return (MI == NULL); } - MachineBasicBlock &getMachineBasicBlock() const { return *MBB; } + const MachineInstr* getMachineInstr() const { return MI; } + const MachineOpCode getOpCode() const { return MI->getOpCode(); } + bool isDummyNode() const { return (MI == NULL); } + MachineBasicBlock &getMachineBasicBlock() const { return *MBB; } - int getOrigIndexInBB() const { return origIndexInBB; } + int getOrigIndexInBB() const { return origIndexInBB; } + void print(std::ostream &os) const; }; class SchedGraph : public SchedGraphCommon { @@ -56,15 +59,15 @@ typedef hash_map::const_iterator iterator; typedef hash_map::const_iterator const_iterator; - MachineBasicBlock& getBasicBlock() const{return MBB;} - const unsigned int getNumNodes() const { return GraphMap.size()+2; } + MachineBasicBlock& getBasicBlock() const{return MBB;} + const unsigned int getNumNodes() const { return GraphMap.size()+2; } SchedGraphNode* getGraphNodeForInstr(const MachineInstr* MI) const { const_iterator onePair = find(MI); return (onePair != end())? onePair->second : NULL; } // Debugging support - void dump () const; + void dump() const; protected: SchedGraph(MachineBasicBlock& mbb, const TargetMachine& TM); @@ -89,12 +92,9 @@ private: friend class SchedGraphSet; // give access to ctor - - - + inline void noteGraphNodeForInstr (const MachineInstr* minstr, - SchedGraphNode* node) - { + SchedGraphNode* node) { assert((*this)[minstr] == NULL); (*this)[minstr] = node; } @@ -102,50 +102,46 @@ // // Graph builder // - void buildGraph (const TargetMachine& target); + void buildGraph(const TargetMachine& target); - void buildNodesForBB (const TargetMachine& target, - MachineBasicBlock &MBB, - std::vector& memNV, - std::vector& callNV, - RegToRefVecMap& regToRefVecMap, - ValueToDefVecMap& valueToDefVecMap); - - - void findDefUseInfoAtInstr (const TargetMachine& target, - SchedGraphNode* node, - std::vector& memNV, - std::vector& callNV, - RegToRefVecMap& regToRefVecMap, - ValueToDefVecMap& valueToDefVecMap); + void buildNodesForBB(const TargetMachine& target,MachineBasicBlock &MBB, + std::vector& memNV, + std::vector& callNV, + RegToRefVecMap& regToRefVecMap, + ValueToDefVecMap& valueToDefVecMap); + + void findDefUseInfoAtInstr(const TargetMachine& target, SchedGraphNode* node, + std::vector& memNV, + std::vector& callNV, + RegToRefVecMap& regToRefVecMap, + ValueToDefVecMap& valueToDefVecMap); - void addEdgesForInstruction(const MachineInstr& minstr, - const ValueToDefVecMap& valueToDefVecMap, - const TargetMachine& target); - - void addCDEdges (const TerminatorInst* term, - const TargetMachine& target); - - void addMemEdges (const std::vector& memNod, - const TargetMachine& target); - - void addCallCCEdges (const std::vector& memNod, - MachineBasicBlock& bbMvec, - const TargetMachine& target); - void addCallDepEdges (const std::vector& callNV, - const TargetMachine& target); - - void addMachineRegEdges (RegToRefVecMap& regToRefVecMap, - const TargetMachine& target); - - void addEdgesForValue (SchedGraphNode* refNode, - const RefVec& defVec, - const Value* defValue, - bool refNodeIsDef, - bool refNodeIsDefAndUse, - const TargetMachine& target); - void addDummyEdges(); + void addEdgesForInstruction(const MachineInstr& minstr, + const ValueToDefVecMap& valueToDefVecMap, + const TargetMachine& target); + + void addCDEdges(const TerminatorInst* term, const TargetMachine& target); + + void addMemEdges(const std::vector& memNod, + const TargetMachine& target); + + void addCallCCEdges(const std::vector& memNod, + MachineBasicBlock& bbMvec, + const TargetMachine& target); + + void addCallDepEdges(const std::vector& callNV, + const TargetMachine& target); + + void addMachineRegEdges(RegToRefVecMap& regToRefVecMap, + const TargetMachine& target); + + void addEdgesForValue(SchedGraphNode* refNode, const RefVec& defVec, + const Value* defValue, bool refNodeIsDef, + bool refNodeIsDefAndUse, + const TargetMachine& target); + + void addDummyEdges(); }; @@ -156,7 +152,7 @@ std::vector Graphs; // Graph builder - void buildGraphsForMethod (const Function *F, const TargetMachine& target); + void buildGraphsForMethod(const Function *F, const TargetMachine& target); inline void addGraph(SchedGraph* graph) { assert(graph != NULL); @@ -164,7 +160,7 @@ } public: - SchedGraphSet(const Function * function, const TargetMachine& target); + SchedGraphSet(const Function *function, const TargetMachine& target); ~SchedGraphSet(); //iterators @@ -200,7 +196,7 @@ // operator*() differs for pred or succ iterator inline _NodeType* operator*() const { return (_NodeType*)(*oi)->getSrc(); } - inline _NodeType* operator->() const { return operator*(); } + inline _NodeType* operator->() const { return operator*(); } inline _EdgeType* getEdge() const { return *(oi); } @@ -228,7 +224,7 @@ inline bool operator!=(const _Self& x) const { return !operator==(x); } inline _NodeType* operator*() const { return (_NodeType*)(*oi)->getSink(); } - inline _NodeType* operator->() const { return operator*(); } + inline _NodeType* operator->() const { return operator*(); } inline _EdgeType* getEdge() const { return *(oi); } @@ -252,16 +248,16 @@ typedef SGPredIterator sg_pred_const_iterator; -inline sg_pred_iterator pred_begin( SchedGraphNode *N) { +inline sg_pred_iterator pred_begin(SchedGraphNode *N) { return sg_pred_iterator(N->beginInEdges()); } -inline sg_pred_iterator pred_end( SchedGraphNode *N) { +inline sg_pred_iterator pred_end(SchedGraphNode *N) { return sg_pred_iterator(N->endInEdges()); } inline sg_pred_const_iterator pred_begin(const SchedGraphNode *N) { return sg_pred_const_iterator(N->beginInEdges()); } -inline sg_pred_const_iterator pred_end( const SchedGraphNode *N) { +inline sg_pred_const_iterator pred_end(const SchedGraphNode *N) { return sg_pred_const_iterator(N->endInEdges()); } @@ -275,16 +271,16 @@ typedef SGSuccIterator sg_succ_const_iterator; -inline sg_succ_iterator succ_begin( SchedGraphNode *N) { +inline sg_succ_iterator succ_begin(SchedGraphNode *N) { return sg_succ_iterator(N->beginOutEdges()); } -inline sg_succ_iterator succ_end( SchedGraphNode *N) { +inline sg_succ_iterator succ_end(SchedGraphNode *N) { return sg_succ_iterator(N->endOutEdges()); } inline sg_succ_const_iterator succ_begin(const SchedGraphNode *N) { return sg_succ_const_iterator(N->beginOutEdges()); } -inline sg_succ_const_iterator succ_end( const SchedGraphNode *N) { +inline sg_succ_const_iterator succ_end(const SchedGraphNode *N) { return sg_succ_const_iterator(N->endOutEdges()); } @@ -318,9 +314,5 @@ return succ_end(N); } }; - - -std::ostream &operator<<(std::ostream& os, const SchedGraphEdge& edge); -std::ostream &operator<<(std::ostream &os, const SchedGraphNode& node); #endif Index: llvm/lib/CodeGen/InstrSched/SchedGraphCommon.cpp diff -u llvm/lib/CodeGen/InstrSched/SchedGraphCommon.cpp:1.1 llvm/lib/CodeGen/InstrSched/SchedGraphCommon.cpp:1.2 --- llvm/lib/CodeGen/InstrSched/SchedGraphCommon.cpp:1.1 Mon Aug 25 17:42:20 2003 +++ llvm/lib/CodeGen/InstrSched/SchedGraphCommon.cpp Tue Aug 26 21:42:58 2003 @@ -1,107 +1,78 @@ +//===- SchedGraphCommon.cpp - Scheduling Graphs Base Class- ---------------===// +// +// Scheduling graph base class that contains common information for SchedGraph +// and ModuloSchedGraph scheduling graphs. +// +//===----------------------------------------------------------------------===// + #include "llvm/CodeGen/SchedGraphCommon.h" #include "Support/STLExtras.h" class SchedGraphCommon; -// +// // class SchedGraphEdge // - -/*ctor*/ SchedGraphEdge::SchedGraphEdge(SchedGraphNodeCommon* _src, SchedGraphNodeCommon* _sink, SchedGraphEdgeDepType _depType, unsigned int _depOrderType, int _minDelay) - : src(_src), - sink(_sink), - depType(_depType), - depOrderType(_depOrderType), - minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), - val(NULL) -{ + : src(_src), sink(_sink), depType(_depType), depOrderType(_depOrderType), + minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), val(NULL) { + iteDiff=0; assert(src != sink && "Self-loop in scheduling graph!"); src->addOutEdge(this); sink->addInEdge(this); } - -/*ctor*/ SchedGraphEdge::SchedGraphEdge(SchedGraphNodeCommon* _src, SchedGraphNodeCommon* _sink, const Value* _val, unsigned int _depOrderType, int _minDelay) - : src(_src), - sink(_sink), - depType(ValueDep), - depOrderType(_depOrderType), - minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), - val(_val) -{ + : src(_src), sink(_sink), depType(ValueDep), depOrderType(_depOrderType), + minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), val(_val) { iteDiff=0; assert(src != sink && "Self-loop in scheduling graph!"); src->addOutEdge(this); sink->addInEdge(this); } - -/*ctor*/ SchedGraphEdge::SchedGraphEdge(SchedGraphNodeCommon* _src, SchedGraphNodeCommon* _sink, unsigned int _regNum, unsigned int _depOrderType, int _minDelay) - : src(_src), - sink(_sink), - depType(MachineRegister), + : src(_src), sink(_sink), depType(MachineRegister), depOrderType(_depOrderType), minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), - machineRegNum(_regNum) -{ + machineRegNum(_regNum) { iteDiff=0; assert(src != sink && "Self-loop in scheduling graph!"); src->addOutEdge(this); sink->addInEdge(this); } - -/*ctor*/ SchedGraphEdge::SchedGraphEdge(SchedGraphNodeCommon* _src, SchedGraphNodeCommon* _sink, ResourceId _resourceId, int _minDelay) - : src(_src), - sink(_sink), - depType(MachineResource), - depOrderType(NonDataDep), + : src(_src), sink(_sink), depType(MachineResource), depOrderType(NonDataDep), minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), - resourceId(_resourceId) -{ + resourceId(_resourceId) { iteDiff=0; assert(src != sink && "Self-loop in scheduling graph!"); src->addOutEdge(this); sink->addInEdge(this); } -/*dtor*/ -SchedGraphEdge::~SchedGraphEdge() -{ -} - -void SchedGraphEdge::dump(int indent) const { - std::cerr << std::string(indent*2, ' ') << *this; -} -/*ctor*/ - -SchedGraphNodeCommon::SchedGraphNodeCommon(unsigned _nodeId) - :ID(_nodeId), - latency(0){ - +void SchedGraphEdge::dump(int indent) const { + std::cerr << std::string(indent*2, ' ') << *this; } /*dtor*/ @@ -112,126 +83,88 @@ deleter); } - -void SchedGraphNodeCommon::dump(int indent) const { - std::cerr << std::string(indent*2, ' ') << *this; -} - - -inline void -SchedGraphNodeCommon::addInEdge(SchedGraphEdge* edge) -{ - inEdges.push_back(edge); -} - - -inline void -SchedGraphNodeCommon::addOutEdge(SchedGraphEdge* edge) -{ - outEdges.push_back(edge); -} - -inline void -SchedGraphNodeCommon::removeInEdge(const SchedGraphEdge* edge) -{ +void SchedGraphNodeCommon::removeInEdge(const SchedGraphEdge* edge) { assert(edge->getSink() == this); for (iterator I = beginInEdges(); I != endInEdges(); ++I) - if ((*I) == edge) - { - inEdges.erase(I); - break; - } + if ((*I) == edge) { + inEdges.erase(I); + break; + } } -inline void -SchedGraphNodeCommon::removeOutEdge(const SchedGraphEdge* edge) -{ +void SchedGraphNodeCommon::removeOutEdge(const SchedGraphEdge* edge) { assert(edge->getSrc() == this); for (iterator I = beginOutEdges(); I != endOutEdges(); ++I) - if ((*I) == edge) - { - outEdges.erase(I); - break; - } + if ((*I) == edge) { + outEdges.erase(I); + break; + } } - -//class SchedGraphCommon - -/*ctor*/ -SchedGraphCommon::SchedGraphCommon() -{ +void SchedGraphNodeCommon::dump(int indent) const { + std::cerr << std::string(indent*2, ' ') << *this; } +//class SchedGraphCommon -/*dtor*/ -SchedGraphCommon::~SchedGraphCommon() -{ - +SchedGraphCommon::~SchedGraphCommon() { delete graphRoot; delete graphLeaf; } -void -SchedGraphCommon::eraseIncomingEdges(SchedGraphNodeCommon* node, bool addDummyEdges) -{ +void SchedGraphCommon::eraseIncomingEdges(SchedGraphNodeCommon* node, + bool addDummyEdges) { // Delete and disconnect all in-edges for the node for (SchedGraphNodeCommon::iterator I = node->beginInEdges(); - I != node->endInEdges(); ++I) - { - SchedGraphNodeCommon* srcNode = (*I)->getSrc(); - srcNode->removeOutEdge(*I); - delete *I; + I != node->endInEdges(); ++I) { + SchedGraphNodeCommon* srcNode = (*I)->getSrc(); + srcNode->removeOutEdge(*I); + delete *I; + + if (addDummyEdges && srcNode != getRoot() && + srcNode->beginOutEdges() == srcNode->endOutEdges()) { - if (addDummyEdges && - srcNode != getRoot() && - srcNode->beginOutEdges() == srcNode->endOutEdges()) - { // srcNode has no more out edges, so add an edge to dummy EXIT node - assert(node != getLeaf() && "Adding edge that was just removed?"); - (void) new SchedGraphEdge(srcNode, getLeaf(), - SchedGraphEdge::CtrlDep, SchedGraphEdge::NonDataDep, 0); - } + // srcNode has no more out edges, so add an edge to dummy EXIT node + assert(node != getLeaf() && "Adding edge that was just removed?"); + (void) new SchedGraphEdge(srcNode, getLeaf(), + SchedGraphEdge::CtrlDep, + SchedGraphEdge::NonDataDep, 0); } + } node->inEdges.clear(); } -void -SchedGraphCommon::eraseOutgoingEdges(SchedGraphNodeCommon* node, bool addDummyEdges) -{ +void SchedGraphCommon::eraseOutgoingEdges(SchedGraphNodeCommon* node, + bool addDummyEdges) { // Delete and disconnect all out-edges for the node for (SchedGraphNodeCommon::iterator I = node->beginOutEdges(); - I != node->endOutEdges(); ++I) - { - SchedGraphNodeCommon* sinkNode = (*I)->getSink(); - sinkNode->removeInEdge(*I); - delete *I; + I != node->endOutEdges(); ++I) { + SchedGraphNodeCommon* sinkNode = (*I)->getSink(); + sinkNode->removeInEdge(*I); + delete *I; + + if (addDummyEdges && + sinkNode != getLeaf() && + sinkNode->beginInEdges() == sinkNode->endInEdges()) { - if (addDummyEdges && - sinkNode != getLeaf() && - sinkNode->beginInEdges() == sinkNode->endInEdges()) - { //sinkNode has no more in edges, so add an edge from dummy ENTRY node - assert(node != getRoot() && "Adding edge that was just removed?"); - (void) new SchedGraphEdge(getRoot(), sinkNode, - SchedGraphEdge::CtrlDep, SchedGraphEdge::NonDataDep, 0); - } + //sinkNode has no more in edges, so add an edge from dummy ENTRY node + assert(node != getRoot() && "Adding edge that was just removed?"); + (void) new SchedGraphEdge(getRoot(), sinkNode, + SchedGraphEdge::CtrlDep, + SchedGraphEdge::NonDataDep, 0); } + } node->outEdges.clear(); } -void -SchedGraphCommon::eraseIncidentEdges(SchedGraphNodeCommon* node, bool addDummyEdges) -{ +void SchedGraphCommon::eraseIncidentEdges(SchedGraphNodeCommon* node, + bool addDummyEdges) { this->eraseIncomingEdges(node, addDummyEdges); this->eraseOutgoingEdges(node, addDummyEdges); } -std::ostream &operator<<(std::ostream &os, const SchedGraphNodeCommon& node) -{ - - return os; -} From tbrethou at cs.uiuc.edu Tue Aug 26 21:46:01 2003 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Tue Aug 26 21:46:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SchedGraphCommon.h Message-ID: <200308270245.VAA07855@tank.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SchedGraphCommon.h updated: 1.1 -> 1.2 --- Log message: Cleaned up the code (spacing, not needed headers) and changed ostream function. Also made some functions inline. --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/SchedGraphCommon.h diff -u llvm/include/llvm/CodeGen/SchedGraphCommon.h:1.1 llvm/include/llvm/CodeGen/SchedGraphCommon.h:1.2 --- llvm/include/llvm/CodeGen/SchedGraphCommon.h:1.1 Mon Aug 25 18:12:23 2003 +++ llvm/include/llvm/CodeGen/SchedGraphCommon.h Tue Aug 26 21:45:08 2003 @@ -8,11 +8,8 @@ #ifndef LLVM_CODEGEN_SCHEDGRAPHCOMMON_H #define LLVM_CODEGEN_SCHEDGRAPHCOMMON_H -#include -#include #include "llvm/Value.h" - class SchedGraphEdge; class SchedGraphNode; @@ -24,8 +21,8 @@ const ResourceId MachineIntRegsRID = -3; // use +ve numbers for actual regs const ResourceId MachineFPRegsRID = -4; // use +ve numbers for actual regs -//*********************** Public Class Declarations ************************/ +//*********************** Public Class Declarations ************************/ class SchedGraphNodeCommon { protected: unsigned ID; @@ -33,59 +30,67 @@ std::vector outEdges; int latency; - friend std::ostream& operator<<(std::ostream& os, const SchedGraphNode& node); - public: - typedef std::vector:: iterator iterator; - typedef std::vector::const_iterator const_iterator; - typedef std::vector:: reverse_iterator reverse_iterator; + typedef std::vector::iterator iterator; + typedef std::vector::const_iterator const_iterator; + typedef std::vector::reverse_iterator reverse_iterator; typedef std::vector::const_reverse_iterator const_reverse_iterator; // Accessor methods - unsigned getNodeId () const { return ID; } - int getLatency () const { return latency; } - unsigned getNumInEdges () const { return inEdges.size(); } - unsigned getNumOutEdges () const { return outEdges.size(); } + unsigned getNodeId() const { return ID; } + int getLatency() const { return latency; } + unsigned getNumInEdges() const { return inEdges.size(); } + unsigned getNumOutEdges() const { return outEdges.size(); } // Iterators - iterator beginInEdges () { return inEdges.begin(); } - iterator endInEdges () { return inEdges.end(); } - iterator beginOutEdges () { return outEdges.begin(); } - iterator endOutEdges () { return outEdges.end(); } - - const_iterator beginInEdges () const { return inEdges.begin(); } - const_iterator endInEdges () const { return inEdges.end(); } - const_iterator beginOutEdges () const { return outEdges.begin(); } - const_iterator endOutEdges () const { return outEdges.end(); } + iterator beginInEdges() { return inEdges.begin(); } + iterator endInEdges() { return inEdges.end(); } + iterator beginOutEdges() { return outEdges.begin(); } + iterator endOutEdges() { return outEdges.end(); } + + const_iterator beginInEdges() const { return inEdges.begin(); } + const_iterator endInEdges() const { return inEdges.end(); } + const_iterator beginOutEdges() const { return outEdges.begin(); } + const_iterator endOutEdges() const { return outEdges.end(); } + void dump(int indent=0) const; // Debugging support - friend std::ostream& operator<<(std::ostream& os, const SchedGraphNodeCommon& node); - - void dump (int indent=0) const; - + virtual void print(std::ostream &os) const = 0; + protected: friend class SchedGraph; friend class SchedGraphCommon; friend class SchedGraphEdge; // give access for adding edges - //friend class ModuloSchedGraph; - void addInEdge (SchedGraphEdge* edge); - void addOutEdge (SchedGraphEdge* edge); - void removeInEdge (const SchedGraphEdge* edge); - void removeOutEdge (const SchedGraphEdge* edge); - // disable default constructor and provide a ctor for single-block graphs SchedGraphNodeCommon(); // DO NOT IMPLEMENT - SchedGraphNodeCommon(unsigned Id); - + inline SchedGraphNodeCommon(unsigned Id) : ID(Id), latency(0) {} virtual ~SchedGraphNodeCommon(); + + //Functions to add and remove edges + inline void addInEdge(SchedGraphEdge* edge) { inEdges.push_back(edge); } + inline void addOutEdge(SchedGraphEdge* edge) { outEdges.push_back(edge); } + void removeInEdge(const SchedGraphEdge* edge); + void removeOutEdge(const SchedGraphEdge* edge); }; +// ostream << operator for SchedGraphNode class +inline std::ostream &operator<<(std::ostream &os, + const SchedGraphNodeCommon &node) { + node.print(os); + return os; +} + + + +// +// SchedGraphEdge - Edge class to represent dependencies +// class SchedGraphEdge { public: enum SchedGraphEdgeDepType { @@ -99,117 +104,107 @@ SchedGraphNodeCommon* src; SchedGraphNodeCommon* sink; SchedGraphEdgeDepType depType; - unsigned int depOrderType; - int minDelay; // cached latency (assumes fixed target arch) - int iteDiff; + unsigned int depOrderType; + int minDelay; // cached latency (assumes fixed target arch) + int iteDiff; union { const Value* val; int machineRegNum; ResourceId resourceId; }; - + public: // For all constructors, if minDelay is unspecified, minDelay is // set to _src->getLatency(). + // constructor for CtrlDep or MemoryDep edges, selected by 3rd argument - /*ctor*/ SchedGraphEdge(SchedGraphNodeCommon* _src, - SchedGraphNodeCommon* _sink, - SchedGraphEdgeDepType _depType, - unsigned int _depOrderType, - int _minDelay = -1); + SchedGraphEdge(SchedGraphNodeCommon* _src, SchedGraphNodeCommon* _sink, + SchedGraphEdgeDepType _depType, unsigned int _depOrderType, + int _minDelay = -1); // constructor for explicit value dependence (may be true/anti/output) - /*ctor*/ SchedGraphEdge(SchedGraphNodeCommon* _src, - SchedGraphNodeCommon* _sink, - const Value* _val, - unsigned int _depOrderType, - int _minDelay = -1); + SchedGraphEdge(SchedGraphNodeCommon* _src, SchedGraphNodeCommon* _sink, + const Value* _val, unsigned int _depOrderType, + int _minDelay = -1); // constructor for machine register dependence - /*ctor*/ SchedGraphEdge(SchedGraphNodeCommon* _src, - SchedGraphNodeCommon* _sink, - unsigned int _regNum, - unsigned int _depOrderType, - int _minDelay = -1); + SchedGraphEdge(SchedGraphNodeCommon* _src,SchedGraphNodeCommon* _sink, + unsigned int _regNum, unsigned int _depOrderType, + int _minDelay = -1); // constructor for any other machine resource dependences. // DataDepOrderType is always NonDataDep. It it not an argument to // avoid overloading ambiguity with previous constructor. - /*ctor*/ SchedGraphEdge(SchedGraphNodeCommon* _src, - SchedGraphNodeCommon* _sink, - ResourceId _resourceId, - int _minDelay = -1); - - /*dtor*/ ~SchedGraphEdge(); - - SchedGraphNodeCommon* getSrc () const { return src; } - SchedGraphNodeCommon* getSink () const { return sink; } - int getMinDelay () const { return minDelay; } - SchedGraphEdgeDepType getDepType () const { return depType; } + SchedGraphEdge(SchedGraphNodeCommon* _src, SchedGraphNodeCommon* _sink, + ResourceId _resourceId, int _minDelay = -1); - const Value* getValue () const { + ~SchedGraphEdge(); + + SchedGraphNodeCommon* getSrc() const { return src; } + SchedGraphNodeCommon* getSink() const { return sink; } + int getMinDelay() const { return minDelay; } + SchedGraphEdgeDepType getDepType() const { return depType; } + + const Value* getValue() const { assert(depType == ValueDep); return val; } - int getMachineReg () const { + + int getMachineReg() const { assert(depType == MachineRegister); return machineRegNum; } - int getResourceId () const { + + int getResourceId() const { assert(depType == MachineResource); return resourceId; } - void setIteDiff (int _iteDiff) { + + void setIteDiff(int _iteDiff) { iteDiff = _iteDiff; } - int getIteDiff (){ + + int getIteDiff() { return iteDiff; } public: - // // Debugging support - // - friend std::ostream& operator<<(std::ostream& os, const SchedGraphEdge& edge); - - void dump (int indent=0) const; + void print(std::ostream &os) const; + void dump(int indent=0) const; private: // disable default ctor - /*ctor*/ SchedGraphEdge(); // DO NOT IMPLEMENT + SchedGraphEdge(); // DO NOT IMPLEMENT }; +// ostream << operator for SchedGraphNode class +inline std::ostream &operator<<(std::ostream &os, const SchedGraphEdge &edge) { + edge.print(os); + return os; +} class SchedGraphCommon { protected: - SchedGraphNodeCommon* graphRoot; // the root and leaf are not inserted - SchedGraphNodeCommon* graphLeaf; // in the hash_map (see getNumNodes()) + SchedGraphNodeCommon* graphRoot; // the root and leaf are not inserted + SchedGraphNodeCommon* graphLeaf; // in the hash_map (see getNumNodes()) public: // // Accessor methods // - SchedGraphNodeCommon* getRoot() const { return graphRoot; } - SchedGraphNodeCommon* getLeaf() const { return graphLeaf; } + SchedGraphNodeCommon* getRoot() const { return graphRoot; } + SchedGraphNodeCommon* getLeaf() const { return graphLeaf; } // // Delete nodes or edges from the graph. // - void eraseNode (SchedGraphNodeCommon* node); - - void eraseIncomingEdges (SchedGraphNodeCommon* node, - bool addDummyEdges = true); - - void eraseOutgoingEdges (SchedGraphNodeCommon* node, - bool addDummyEdges = true); - - void eraseIncidentEdges (SchedGraphNodeCommon* node, - bool addDummyEdges = true); + void eraseNode(SchedGraphNodeCommon* node); + void eraseIncomingEdges(SchedGraphNodeCommon* node, bool addDummyEdges = true); + void eraseOutgoingEdges(SchedGraphNodeCommon* node, bool addDummyEdges = true); + void eraseIncidentEdges(SchedGraphNodeCommon* node, bool addDummyEdges = true); - /*ctor*/ SchedGraphCommon (); - /*dtor*/ ~SchedGraphCommon (); - + SchedGraphCommon(); + ~SchedGraphCommon(); }; - - #endif From lattner at cs.uiuc.edu Tue Aug 26 23:51:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 26 23:51:01 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/c++-exception.h Message-ID: <200308270450.XAA12324@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: c++-exception.h updated: 1.2 -> 1.3 --- Log message: C++ify, add new get_cxx_exception function to convert from generic llvm_exceptions to llvm_cxx_exception's --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/c++-exception.h diff -u llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.2 llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.3 --- llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.2 Tue Aug 26 18:46:53 2003 +++ llvm/runtime/GCCLibraries/libexception/c++-exception.h Tue Aug 26 23:50:45 2003 @@ -10,8 +10,9 @@ #include "exception.h" #include +#include -typedef struct llvm_cxx_exception { +struct llvm_cxx_exception { /* TypeInfo - A pointer to the C++ std::type_info object for this exception * class. This is required because the class may not be polymorphic. */ @@ -42,9 +43,12 @@ * this structure without breaking binary compatibility. */ llvm_exception BaseException; -} llvm_cxx_exception; - +}; +inline llvm_cxx_exception *get_cxx_exception(llvm_exception *E) { + assert(E->ExceptionType == CXXException && "Not a C++ exception?"); + return (llvm_cxx_exception*)(E+1)-1; +} extern "C" { void *__llvm_cxxeh_allocate_exception(unsigned NumBytes); From lattner at cs.uiuc.edu Tue Aug 26 23:51:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 26 23:51:03 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/exception.h Message-ID: <200308270450.XAA12312@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: exception.h updated: 1.1 -> 1.2 --- Log message: Remove Cisms. We love C++ --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/exception.h diff -u llvm/runtime/GCCLibraries/libexception/exception.h:1.1 llvm/runtime/GCCLibraries/libexception/exception.h:1.2 --- llvm/runtime/GCCLibraries/libexception/exception.h:1.1 Mon Aug 25 17:35:36 2003 +++ llvm/runtime/GCCLibraries/libexception/exception.h Tue Aug 26 23:50:12 2003 @@ -8,12 +8,12 @@ #ifndef EXCEPTION_H #define EXCEPTION_H -typedef struct llvm_exception { +struct llvm_exception { // ExceptionDestructor - This call-back function is used to destroy the // current exception, without requiring the caller to know what the concrete // exception type is. // - void (*ExceptionDestructor)(struct llvm_exception *); + void (*ExceptionDestructor)(llvm_exception *); // ExceptionType - This field identifies what runtime library this exception // came from. Currently defined values are: @@ -24,14 +24,14 @@ unsigned ExceptionType; // Next - This points to the next exception in the current stack. - struct llvm_exception *Next; + llvm_exception *Next; // HandlerCount - This is a count of the number of handlers which have // currently caught this exception. If the handler is caught and this number // falls to zero, the exception is destroyed. // unsigned HandlerCount; -} llvm_exception; +}; enum { ErrorException = 0, From lattner at cs.uiuc.edu Tue Aug 26 23:52:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 26 23:52:00 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/c++-exception.cpp Message-ID: <200308270451.XAA12336@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: c++-exception.cpp updated: 1.2 -> 1.3 --- Log message: Fix several _killer_ bugs. This now actually WORKS for really complex testcases :) --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/c++-exception.cpp diff -u llvm/runtime/GCCLibraries/libexception/c++-exception.cpp:1.2 llvm/runtime/GCCLibraries/libexception/c++-exception.cpp:1.3 --- llvm/runtime/GCCLibraries/libexception/c++-exception.cpp:1.2 Tue Aug 26 18:46:53 2003 +++ llvm/runtime/GCCLibraries/libexception/c++-exception.cpp Tue Aug 26 23:51:26 2003 @@ -9,7 +9,6 @@ #include "c++-exception.h" #include -#include //===----------------------------------------------------------------------===// // Generic exception support @@ -75,8 +74,7 @@ // exception. // static void cxx_destructor(llvm_exception *LE) { - void *ObjectPtr = LE+1; - llvm_cxx_exception *E = (llvm_cxx_exception *)ObjectPtr - 1; + llvm_cxx_exception *E = get_cxx_exception(LE); // The exception is no longer caught. assert(CaughtExceptionStack == LE && @@ -132,7 +130,7 @@ // to see if TypeID matches and, if so, to adjust the exception object // pointer. // - llvm_cxx_exception *E = (llvm_cxx_exception*)UncaughtExceptionStack; + llvm_cxx_exception *E = get_cxx_exception(UncaughtExceptionStack); // ThrownPtr is a pointer to the object being thrown... void *ThrownPtr = E+1; @@ -170,7 +168,7 @@ // The exception is now caught. E->Next = CaughtExceptionStack; - CaughtExceptionStack = E->Next; + CaughtExceptionStack = E; // Increment the handler count for this exception. E->HandlerCount++; @@ -204,10 +202,8 @@ assert(E && "There are no caught exceptions!"); // If this is the last handler using the exception, destroy it now! - if (--E->HandlerCount == 0) { - CaughtExceptionStack = E->Next; // Unlink from the stack + if (--E->HandlerCount == 0) E->ExceptionDestructor(E); // Release memory for the exception - } } // __llvm_cxxeh_rethrow - This function turns the top-level caught exception @@ -229,9 +225,6 @@ CaughtExceptionStack = E->Next; E->Next = UncaughtExceptionStack; UncaughtExceptionStack = E; - - // Decrement the number of handlers which are using the exception. - --E->HandlerCount; // Return to the caller, which should perform the unwind now. } From lattner at cs.uiuc.edu Tue Aug 26 23:58:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Aug 26 23:58:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/EH/simple_throw.cpp throw_rethrow_test.cpp Message-ID: <200308270457.XAA12454@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend/EH: simple_throw.cpp added (r1.1) throw_rethrow_test.cpp added (r1.1) --- Log message: New testcases, which WORK with LLVMG++ and the CBE. --- Diffs of the changes: Index: llvm/test/Regression/C++Frontend/EH/simple_throw.cpp diff -c /dev/null llvm/test/Regression/C++Frontend/EH/simple_throw.cpp:1.1 *** /dev/null Tue Aug 26 23:57:43 2003 --- llvm/test/Regression/C++Frontend/EH/simple_throw.cpp Tue Aug 26 23:57:33 2003 *************** *** 0 **** --- 1,13 ---- + // Test throwing a constant int + #include + + static void foo() { throw 5; } + int main() { + try { + foo(); + } catch (...) { + printf("All ok\n"); + return 0; + } + return 1; + } Index: llvm/test/Regression/C++Frontend/EH/throw_rethrow_test.cpp diff -c /dev/null llvm/test/Regression/C++Frontend/EH/throw_rethrow_test.cpp:1.1 *** /dev/null Tue Aug 26 23:57:43 2003 --- llvm/test/Regression/C++Frontend/EH/throw_rethrow_test.cpp Tue Aug 26 23:57:33 2003 *************** *** 0 **** --- 1,40 ---- + // This tests hard situations for throwing, including the case where an + // exception is active in more than one handler at a time (ie, it needs + // refcounting) + #include + + struct foo { + int i; + foo() : i(1) { } + foo(const foo&) : i(2) {} + }; + + int callee(unsigned i) { + if (i < 3) throw (int)i; + if (i < 6) throw 1.0; + if (i < 9) throw foo(); + return 0; + } + + void rethrow() { + throw; + } + + int main() { + for (unsigned i = 0; i < 10; ++i) { + try { + return callee(i); + } catch (foo &F) { + try { + rethrow(); + } catch (foo &F) { + std::printf("%d: 3\n", i); + } + } catch (int) { + std::printf("%d: 1\n", i); + } catch (...) { + std::printf("%d: 2\n", i); + } + } + } + From criswell at cs.uiuc.edu Wed Aug 27 08:43:03 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Wed Aug 27 08:43:03 2003 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileLexer.l TableGen.cpp Message-ID: <200308271342.IAA02595@choi.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileLexer.l updated: 1.12 -> 1.13 TableGen.cpp updated: 1.19 -> 1.20 --- Log message: Added an option to TableGen that allows users to specify a directory in which to find include files. TableGen will load include files from this directory if it cannot find them in the current directory. This feature was needed for building code inside the object tree (a la autoconf style). TODO: Allow for multiple -I options to specify a list of directories to search. --- Diffs of the changes: Index: llvm/utils/TableGen/FileLexer.l diff -u llvm/utils/TableGen/FileLexer.l:1.12 llvm/utils/TableGen/FileLexer.l:1.13 --- llvm/utils/TableGen/FileLexer.l:1.12 Sun Aug 10 17:04:25 2003 +++ llvm/utils/TableGen/FileLexer.l Wed Aug 27 08:41:57 2003 @@ -21,9 +21,13 @@ %{ #include "Record.h" +#include "Support/CommandLine.h" typedef std::pair*> SubClassRefTy; #include "FileParser.h" +// Global variable recording the location of the include directory +std::string IncludeDirectory; + // ParseInt - This has to handle the special case of binary numbers 0b0101 static int ParseInt(const char *Str) { if (Str[0] == '0' && Str[1] == 'b') @@ -61,7 +65,18 @@ int Fileparse(); -void ParseFile(const std::string &Filename) { +// +// Function: ParseFile() +// +// Description: +// This function begins the parsing of the specified tablegen file. +// +// Inputs: +// Filename - A string containing the name of the file to parse. +// IncludeDir - A string containing the directory from which include +// files can be found. +// +void ParseFile(const std::string &Filename, const std::string & IncludeDir) { FILE *F = stdin; if (Filename != "-") { F = fopen(Filename.c_str(), "r"); @@ -75,6 +90,12 @@ IncludeStack.push_back(IncludeRec("", stdin)); } + // + // Record the location of the include directory so that the lexer can find + // it later. + // + IncludeDirectory = IncludeDir; + Filein = F; Filelineno = 1; Fileparse(); @@ -103,8 +124,20 @@ // Open the new input file... yyin = fopen(Filename.c_str(), "r"); if (yyin == 0) { - err() << "Could not find include file '" << Filename << "'!\n"; - abort(); + // + // If we couldn't find the file in the current directory, look for it in + // the include directories. + // + // NOTE: + // Right now, there is only one directory. We need to eventually add + // support for more. + // + Filename = IncludeDirectory + "/" + Filename; + yyin = fopen(Filename.c_str(), "r"); + if (yyin == 0) { + err() << "Could not find include file '" << Filename << "'!\n"; + abort(); + } } // Add the file to our include stack... Index: llvm/utils/TableGen/TableGen.cpp diff -u llvm/utils/TableGen/TableGen.cpp:1.19 llvm/utils/TableGen/TableGen.cpp:1.20 --- llvm/utils/TableGen/TableGen.cpp:1.19 Thu Aug 14 11:05:35 2003 +++ llvm/utils/TableGen/TableGen.cpp Wed Aug 27 08:41:57 2003 @@ -64,10 +64,14 @@ cl::opt InputFilename(cl::Positional, cl::desc(""), cl::init("-")); + + cl::opt + IncludeDir("I", cl::desc("Directory of include files"), + cl::value_desc("directory"), cl::init("")); } -void ParseFile(const std::string &Filename); +void ParseFile(const std::string &Filename, const std::string & IncludeDir); RecordKeeper Records; @@ -398,7 +402,7 @@ int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv); - ParseFile(InputFilename); + ParseFile(InputFilename, IncludeDir); std::ostream *Out = &std::cout; if (OutputFilename != "-") { From tbrethou at cs.uiuc.edu Wed Aug 27 10:13:01 2003 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Wed Aug 27 10:13:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/InstrSched/SchedGraph.h Message-ID: <200308271512.KAA13991@tank.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/InstrSched: SchedGraph.h updated: 1.32 -> 1.33 --- Log message: Added/removed header file --- Diffs of the changes: Index: llvm/lib/CodeGen/InstrSched/SchedGraph.h diff -u llvm/lib/CodeGen/InstrSched/SchedGraph.h:1.32 llvm/lib/CodeGen/InstrSched/SchedGraph.h:1.33 --- llvm/lib/CodeGen/InstrSched/SchedGraph.h:1.32 Tue Aug 26 21:42:58 2003 +++ llvm/lib/CodeGen/InstrSched/SchedGraph.h Wed Aug 27 10:12:24 2003 @@ -20,7 +20,6 @@ #include "Support/hash_map" #include "Support/GraphTraits.h" - class RegToRefVecMap; class ValueToDefVecMap; class RefVec; From tbrethou at niobe.cs.uiuc.edu Wed Aug 27 10:53:02 2003 From: tbrethou at niobe.cs.uiuc.edu (Tanya Brethour) Date: Wed Aug 27 10:53:02 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SchedGraphCommon.h Message-ID: <200308271552.h7RFqYu19666@niobe.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SchedGraphCommon.h updated: 1.2 -> 1.3 --- Log message: (null) --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/SchedGraphCommon.h diff -u llvm/include/llvm/CodeGen/SchedGraphCommon.h:1.2 llvm/include/llvm/CodeGen/SchedGraphCommon.h:1.3 --- llvm/include/llvm/CodeGen/SchedGraphCommon.h:1.2 Tue Aug 26 21:45:08 2003 +++ llvm/include/llvm/CodeGen/SchedGraphCommon.h Wed Aug 27 10:52:23 2003 @@ -139,7 +139,7 @@ SchedGraphEdge(SchedGraphNodeCommon* _src, SchedGraphNodeCommon* _sink, ResourceId _resourceId, int _minDelay = -1); - ~SchedGraphEdge(); + ~SchedGraphEdge() {} SchedGraphNodeCommon* getSrc() const { return src; } SchedGraphNodeCommon* getSink() const { return sink; } @@ -203,7 +203,7 @@ void eraseOutgoingEdges(SchedGraphNodeCommon* node, bool addDummyEdges = true); void eraseIncidentEdges(SchedGraphNodeCommon* node, bool addDummyEdges = true); - SchedGraphCommon(); + SchedGraphCommon() {} ~SchedGraphCommon(); }; From lattner at cs.uiuc.edu Wed Aug 27 13:21:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 27 13:21:03 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/EH/copy_ctor_throw.cpp Message-ID: <200308271820.NAA19957@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend/EH: copy_ctor_throw.cpp added (r1.1) --- Log message: New testcase. Unfortunately, native GCC gets this wrong. Someday we will have to figure out how to deal with this. --- Diffs of the changes: Index: llvm/test/Regression/C++Frontend/EH/copy_ctor_throw.cpp diff -c /dev/null llvm/test/Regression/C++Frontend/EH/copy_ctor_throw.cpp:1.1 *** /dev/null Wed Aug 27 13:20:03 2003 --- llvm/test/Regression/C++Frontend/EH/copy_ctor_throw.cpp Wed Aug 27 13:19:53 2003 *************** *** 0 **** --- 1,25 ---- + /* Test for throwing an exception from the copy ctor of the exception object + * invoked while building an exception. + */ + #include + + struct foo { + foo() {} + foo(const foo &F) { throw 1; } + }; + + int main() { + try { + foo f; + throw f; + } catch (int i) { + printf("Success!\n"); + return 0; + } catch (foo &f) { + printf("Failure: caught a foo!\n"); + return 1; + } catch (...) { + printf("Failure: caught something else!\n"); + return 1; + } + } From lattner at cs.uiuc.edu Wed Aug 27 13:27:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 27 13:27:01 2003 Subject: [llvm-commits] CVS: llvm/Makefile.common Message-ID: <200308271826.NAA16751@neo.cs.uiuc.edu> Changes in directory llvm: Makefile.common updated: 1.128 -> 1.129 --- Log message: Refactor code slightly. Make code compiled with llvmgcc use the warning options as well. Compile with -fshort-enums whether in debug or release mode, because it breaks the ABI --- Diffs of the changes: Index: llvm/Makefile.common diff -u llvm/Makefile.common:1.128 llvm/Makefile.common:1.129 --- llvm/Makefile.common:1.128 Sat Aug 23 10:56:38 2003 +++ llvm/Makefile.common Wed Aug 27 13:26:44 2003 @@ -354,8 +354,9 @@ # Allow gnu extensions... CPPFLAGS += -D_GNU_SOURCE -CompileCommonOpts := -Wall -W -Wwrite-strings -Wno-unused -I$(LEVEL)/include -CompileOptimizeOpts := -O3 -DNDEBUG -finline-functions -fshort-enums +CompileWarnings := -Wall -W -Wwrite-strings -Wno-unused +CompileCommonOpts := $(CompileWarnings) -I$(LEVEL)/include -fshort-enums +CompileOptimizeOpts := -O3 -DNDEBUG -finline-functions # # Compile commands with libtool. @@ -739,11 +740,11 @@ $(BUILD_OBJ_DIR)/Bytecode/%.bc: $(SourceDir)%.cpp $(BUILD_OBJ_DIR)/Bytecode/.dir $(LCC1XX) @echo "Compiling $< to bytecode" - $(VERB) $(LLVMGXX) $(CPPFLAGS) -c $< -o $@ + $(VERB) $(LLVMGXX) $(CompileWarnings) $(CPPFLAGS) -c $< -o $@ $(BUILD_OBJ_DIR)/Bytecode/%.bc: $(SourceDir)%.c $(BUILD_OBJ_DIR)/Bytecode/.dir $(LCC1) @echo "Compiling $< to bytecode" - $(VERB) $(LLVMGCC) $(CPPFLAGS) -c $< -o $@ + $(VERB) $(LLVMGCC) $(CompileWarnings) $(CPPFLAGS) -c $< -o $@ $(BUILD_OBJ_DIR)/Bytecode/%.bc: $(SourceDir)%.ll $(BUILD_OBJ_DIR)/Bytecode/.dir $(LLVMAS) @echo "Compiling $< to bytecode" From brukman at cs.uiuc.edu Wed Aug 27 13:27:04 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Wed Aug 27 13:27:04 2003 Subject: [llvm-commits] CVS: llvm/include/Support/Casting.h Message-ID: <200308271826.NAA19341@zion.cs.uiuc.edu> Changes in directory llvm/include/Support: Casting.h updated: 1.6 -> 1.7 --- Log message: Spell `incompatible' correctly. --- Diffs of the changes: Index: llvm/include/Support/Casting.h diff -u llvm/include/Support/Casting.h:1.6 llvm/include/Support/Casting.h:1.7 --- llvm/include/Support/Casting.h:1.6 Mon Jun 30 16:58:23 2003 +++ llvm/include/Support/Casting.h Wed Aug 27 13:26:28 2003 @@ -184,7 +184,7 @@ // template inline typename cast_retty::ret_type cast(const Y &Val) { - assert(isa(Val) && "cast() argument of uncompatible type!"); + assert(isa(Val) && "cast() argument of incompatible type!"); return cast_convert_val::SimpleType>::doit(Val); } @@ -195,7 +195,7 @@ template inline typename cast_retty::ret_type cast_or_null(Y *Val) { if (Val == 0) return 0; - assert(isa(Val) && "cast_or_null() argument of uncompatible type!"); + assert(isa(Val) && "cast_or_null() argument of incompatible type!"); return cast(Val); } From lattner at cs.uiuc.edu Wed Aug 27 14:07:11 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 27 14:07:11 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/EH/copy_ctor_throw.cpp Message-ID: <200308271906.OAA22167@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend/EH: copy_ctor_throw.cpp (r1.1) removed --- Log message: Move the testcase elsewhere --- Diffs of the changes: From gaeke at cs.uiuc.edu Wed Aug 27 15:42:03 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Aug 27 15:42:03 2003 Subject: [llvm-commits] CVS: reopt/test/TEST.reopt.Makefile Message-ID: <200308272041.PAA11312@trinity.cs.uiuc.edu> Changes in directory reopt/test: TEST.reopt.Makefile updated: 1.3 -> 1.4 --- Log message: Don't need to link in libanalysis.a. Turn on -disable-strip to help with debugging. Print out the name of the output file, so it's easier to `less' it afterwards. --- Diffs of the changes: Index: reopt/test/TEST.reopt.Makefile diff -u reopt/test/TEST.reopt.Makefile:1.3 reopt/test/TEST.reopt.Makefile:1.4 --- reopt/test/TEST.reopt.Makefile:1.3 Fri Aug 22 13:33:38 2003 +++ reopt/test/TEST.reopt.Makefile Wed Aug 27 15:40:56 2003 @@ -23,8 +23,7 @@ # Libraries that contain common LLVM code the Reoptimizer depends on REOPTIMIZER_LLVM_SUPPORT_LIBS = $(DESTLIBCURRENT)/libscalaropts.a \ $(DESTLIBCURRENT)/libtransformutils.a $(DESTLIBCURRENT)/vmcore.o \ - $(DESTLIBCURRENT)/libsupport.a $(DESTLIBCURRENT)/bcreader.o \ - $(DESTLIBCURRENT)/libanalysis.a + $(DESTLIBCURRENT)/libsupport.a $(DESTLIBCURRENT)/bcreader.o # Solaris libraries that the Reoptimizer depends on REOPTIMIZER_SOLARIS_SUPPORT_LIBS = -lcpc -lm -lrt -lmalloc @@ -52,7 +51,7 @@ Output/%.reopt-llc.s: Output/%.llvm.bc @echo "=========================================" @echo "Compiling Reoptimizer version of '$(TESTNAME)'" - -$(LOPT) -q -inline -lowerswitch -branch-combine -emitfuncs -instloops $< | $(LLC) $(LLCFLAGS) -disable-sched -f -enable-maps -o $@ + -$(LOPT) -q -inline -lowerswitch -branch-combine -emitfuncs -instloops $< | $(LLC) $(LLCFLAGS) -disable-sched -disable-strip -f -enable-maps -o $@ # 2. Link the instrumented binary with the necessary parts of the # compiler. @@ -65,4 +64,5 @@ Output/%.out-reopt-llc: Output/%.reopt-llc @echo "Running Reoptimizer version of '$(TESTNAME)'" -$(RUNSAFELY) $(STDIN_FILENAME) $@ $< $(RUN_OPTIONS) + @echo "Output in" `pwd`/$@ From lattner at cs.uiuc.edu Wed Aug 27 17:19:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 27 17:19:01 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/Makefile Message-ID: <200308272218.RAA18405@neo.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries: Makefile updated: 1.1 -> 1.2 --- Log message: Hack out libexception temporarily until the Sparc FE is improved --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/Makefile diff -u llvm/runtime/GCCLibraries/Makefile:1.1 llvm/runtime/GCCLibraries/Makefile:1.2 --- llvm/runtime/GCCLibraries/Makefile:1.1 Thu Aug 14 21:33:49 2003 +++ llvm/runtime/GCCLibraries/Makefile Wed Aug 27 17:18:23 2003 @@ -2,6 +2,7 @@ LEVEL = ../.. PARALLEL_DIRS := $(sort $(filter-out Output/, $(filter-out CVS/, $(wildcard */)))) +PARALLEL_DIRS := $(filter-out libexception/, $(PARALLEL_DIRS)) include $(LEVEL)/Makefile.common From lattner at cs.uiuc.edu Wed Aug 27 18:00:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 27 18:00:02 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/exception.h Message-ID: <200308272259.RAA13610@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: exception.h updated: 1.2 -> 1.3 --- Log message: Add throw specs to the functions, remove (void) from the functions --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/exception.h diff -u llvm/runtime/GCCLibraries/libexception/exception.h:1.2 llvm/runtime/GCCLibraries/libexception/exception.h:1.3 --- llvm/runtime/GCCLibraries/libexception/exception.h:1.2 Tue Aug 26 23:50:12 2003 +++ llvm/runtime/GCCLibraries/libexception/exception.h Wed Aug 27 17:58:51 2003 @@ -42,8 +42,8 @@ // Language independent exception handling API... // extern "C" { - bool __llvm_eh_has_uncaught_exception(void); - void *__llvm_eh_current_uncaught_exception_type(unsigned HandlerType); + bool __llvm_eh_has_uncaught_exception() throw(); + void *__llvm_eh_current_uncaught_exception_type(unsigned HandlerType) throw(); } #endif From lattner at cs.uiuc.edu Wed Aug 27 18:01:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 27 18:01:01 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/c++-exception.h Message-ID: <200308272300.SAA13654@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: c++-exception.h updated: 1.3 -> 1.4 --- Log message: Be more type-safe, add throw specs to all functions --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/c++-exception.h diff -u llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.3 llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.4 --- llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.3 Tue Aug 26 23:50:45 2003 +++ llvm/runtime/GCCLibraries/libexception/c++-exception.h Wed Aug 27 17:59:15 2003 @@ -29,14 +29,14 @@ * unexpected which are a result of an exception throw are supposed to use the * value of the handler at the time of the throw, not the currently set value. */ - void *UnexpectedHandler; + void (*UnexpectedHandler)(); /* TerminateHandler - This contains a pointer to the "terminate" handler which * may be registered by the user program with set_terminate. Calls to * unexpected which are a result of an exception throw are supposed to use the * value of the handler at the time of the throw, not the currently set value. */ - void *TerminateHandler; + void (*TerminateHandler)(); /* BaseException - The language independent portion of the exception state. * This is at the end of the record so that we can add additional members to @@ -45,23 +45,37 @@ llvm_exception BaseException; }; -inline llvm_cxx_exception *get_cxx_exception(llvm_exception *E) { +inline llvm_cxx_exception *get_cxx_exception(llvm_exception *E) throw() { assert(E->ExceptionType == CXXException && "Not a C++ exception?"); return (llvm_cxx_exception*)(E+1)-1; } -extern "C" { - void *__llvm_cxxeh_allocate_exception(unsigned NumBytes); - void __llvm_cxxeh_free_exception(void *ObjectPtr); - void __llvm_cxxeh_throw(void *ObjectPtr, const std::type_info *TypeInfoPtr, - void (*DtorPtr)(void*)); - - void * __llvm_cxxeh_current_uncaught_exception_isa(const std::type_info *Ty); - void *__llvm_cxxeh_begin_catch(void); - void *__llvm_cxxeh_begin_catch_if_isa(const std::type_info *CatchType); - void __llvm_cxxeh_end_catch(void); +// Interface to the C++ standard library to get to the terminate and unexpected +// handler stuff. +namespace __cxxabiv1 { + // Invokes given handler, dying appropriately if the user handler was + // so inconsiderate as to return. + extern void __terminate(std::terminate_handler) __attribute__((noreturn)); + extern void __unexpected(std::unexpected_handler) __attribute__((noreturn)); + + // The current installed user handlers. + extern std::terminate_handler __terminate_handler; + extern std::unexpected_handler __unexpected_handler; +} - void __llvm_cxxeh_rethrow(void); +extern "C" { + void *__llvm_cxxeh_allocate_exception(unsigned NumBytes) throw(); + void __llvm_cxxeh_free_exception(void *ObjectPtr) throw(); + void __llvm_cxxeh_throw(void *ObjectPtr, void *TypeInfoPtr, + void (*DtorPtr)(void*)) throw(); + + void * __llvm_cxxeh_current_uncaught_exception_isa(void *Ty) + throw(); + void *__llvm_cxxeh_begin_catch() throw(); + void *__llvm_cxxeh_begin_catch_if_isa(void *CatchType) throw(); + void __llvm_cxxeh_end_catch() /* might throw */; + void __llvm_cxxeh_rethrow() throw(); + void __llvm_cxxeh_check_eh_spec(void *Info, ...); } #endif From lattner at cs.uiuc.edu Wed Aug 27 18:01:04 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Aug 27 18:01:04 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/c++-exception.cpp Message-ID: <200308272300.SAA13649@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: c++-exception.cpp updated: 1.3 -> 1.4 --- Log message: Be more typesafe Call terminate and unexpected where appropriate. Interface to libstdc++ as appropriate Initial cut at implementing function exception specifications --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/c++-exception.cpp diff -u llvm/runtime/GCCLibraries/libexception/c++-exception.cpp:1.3 llvm/runtime/GCCLibraries/libexception/c++-exception.cpp:1.4 --- llvm/runtime/GCCLibraries/libexception/c++-exception.cpp:1.3 Tue Aug 26 23:51:26 2003 +++ llvm/runtime/GCCLibraries/libexception/c++-exception.cpp Wed Aug 27 18:00:11 2003 @@ -9,6 +9,7 @@ #include "c++-exception.h" #include +#include //===----------------------------------------------------------------------===// // Generic exception support @@ -25,7 +26,7 @@ // __llvm_eh_has_uncaught_exception - This is used to implement // std::uncaught_exception. // -bool __llvm_eh_has_uncaught_exception(void) { +bool __llvm_eh_has_uncaught_exception() throw() { return UncaughtExceptionStack != 0; } @@ -33,7 +34,7 @@ // current uncaught exception is of the specified language type. If so, it // returns a pointer to the exception area data. // -void *__llvm_eh_current_uncaught_exception_type(unsigned HandlerType) { +void *__llvm_eh_current_uncaught_exception_type(unsigned HandlerType) throw() { assert(UncaughtExceptionStack && "No uncaught exception!"); if (UncaughtExceptionStack->ExceptionType == HandlerType) return UncaughtExceptionStack+1; @@ -44,11 +45,12 @@ //===----------------------------------------------------------------------===// // C++ Specific exception handling support... // +using namespace __cxxabiv1; // __llvm_cxxeh_allocate_exception - This function allocates space for the // specified number of bytes, plus a C++ exception object header. // -void *__llvm_cxxeh_allocate_exception(unsigned NumBytes) { +void *__llvm_cxxeh_allocate_exception(unsigned NumBytes) throw() { // FIXME: This should eventually have back-up buffers for out-of-memory // situations. // @@ -64,7 +66,7 @@ // into the exception location throws. Otherwise it is called from the C++ // exception object destructor. // -void __llvm_cxxeh_free_exception(void *ObjectPtr) { +void __llvm_cxxeh_free_exception(void *ObjectPtr) throw() { llvm_cxx_exception *E = (llvm_cxx_exception *)ObjectPtr - 1; free(E); } @@ -73,7 +75,7 @@ // exception->ExceptionDestructor function pointer to destroy a caught // exception. // -static void cxx_destructor(llvm_exception *LE) { +static void cxx_destructor(llvm_exception *LE) /* might throw */{ llvm_cxx_exception *E = get_cxx_exception(LE); // The exception is no longer caught. @@ -100,8 +102,8 @@ // evaluated into it, this sets up all of the fields of the exception allowing // it to be thrown. After calling this, the code should call %llvm.unwind // -void __llvm_cxxeh_throw(void *ObjectPtr, const std::type_info *TypeInfoPtr, - void (*DtorPtr)(void*)) { +void __llvm_cxxeh_throw(void *ObjectPtr, void *TypeInfoPtr, + void (*DtorPtr)(void*)) throw() { llvm_cxx_exception *E = (llvm_cxx_exception *)ObjectPtr - 1; E->BaseException.ExceptionDestructor = cxx_destructor; E->BaseException.ExceptionType = CXXException; @@ -109,29 +111,17 @@ UncaughtExceptionStack = &E->BaseException; E->BaseException.HandlerCount = 0; - E->TypeInfo = TypeInfoPtr; + E->TypeInfo = (const std::type_info*)TypeInfoPtr; E->ExceptionObjectDestructor = DtorPtr; - E->UnexpectedHandler = 0; // FIXME - E->TerminateHandler = 0; // FIXME + E->UnexpectedHandler = __unexpected_handler; + E->TerminateHandler = __terminate_handler; } -// __llvm_cxxeh_current_uncaught_exception_isa - This function checks to see if -// the current uncaught exception is a C++ exception, and if it is of the -// specified type id. If so, it returns a pointer to the object adjusted as -// appropriate, otherwise it returns null. -// -void *__llvm_cxxeh_current_uncaught_exception_isa( - const std::type_info *CatchType) { - assert(UncaughtExceptionStack && "No uncaught exception!"); - if (UncaughtExceptionStack->ExceptionType != CXXException) - return 0; // If it's not a c++ exception, it doesn't match! - - // If it is a C++ exception, use the type info object stored in the exception - // to see if TypeID matches and, if so, to adjust the exception object - // pointer. - // - llvm_cxx_exception *E = get_cxx_exception(UncaughtExceptionStack); +// CXXExceptionISA - use the type info object stored in the exception to see if +// TypeID matches and, if so, to adjust the exception object pointer. +// +static void *CXXExceptionISA(llvm_cxx_exception *E, const std::type_info *Type){ // ThrownPtr is a pointer to the object being thrown... void *ThrownPtr = E+1; const std::type_info *ThrownType = E->TypeInfo; @@ -147,19 +137,37 @@ ThrownPtr = *(void **)ThrownPtr; #endif - if (CatchType->__do_catch(ThrownType, &ThrownPtr, 1)) + if (Type->__do_catch(ThrownType, &ThrownPtr, 1)) return ThrownPtr; return 0; } +// __llvm_cxxeh_current_uncaught_exception_isa - This function checks to see if +// the current uncaught exception is a C++ exception, and if it is of the +// specified type id. If so, it returns a pointer to the object adjusted as +// appropriate, otherwise it returns null. +// +void *__llvm_cxxeh_current_uncaught_exception_isa(void *CatchType) throw() { + assert(UncaughtExceptionStack && "No uncaught exception!"); + if (UncaughtExceptionStack->ExceptionType != CXXException) + return 0; // If it's not a c++ exception, it doesn't match! + + // If it is a C++ exception, use the type info object stored in the exception + // to see if TypeID matches and, if so, to adjust the exception object + // pointer. + // + const std::type_info *Info = (const std::type_info *)CatchType; + return CXXExceptionISA(get_cxx_exception(UncaughtExceptionStack), Info); +} + // __llvm_cxxeh_begin_catch - This function is called by "exception handlers", // which transition an exception from being uncaught to being caught. It // returns a pointer to the exception object portion of the exception. This // function must work with foreign exceptions. // -void *__llvm_cxxeh_begin_catch(void) { +void *__llvm_cxxeh_begin_catch() throw() { llvm_exception *E = UncaughtExceptionStack; assert(UncaughtExceptionStack && "There are no uncaught exceptions!?!?"); @@ -183,7 +191,7 @@ // object of the specified type. This function does never succeeds with foreign // exceptions (because they can never be of type CatchType). // -void *__llvm_cxxeh_begin_catch_if_isa(const std::type_info *CatchType) { +void *__llvm_cxxeh_begin_catch_if_isa(void *CatchType) throw() { void *ObjPtr = __llvm_cxxeh_current_uncaught_exception_isa(CatchType); if (!ObjPtr) return 0; @@ -197,7 +205,7 @@ // top-level caught exception, destroying it if this is the last handler for the // exception. // -void __llvm_cxxeh_end_catch(void) { +void __llvm_cxxeh_end_catch() /* might throw */ { llvm_exception *E = CaughtExceptionStack; assert(E && "There are no caught exceptions!"); @@ -206,19 +214,19 @@ E->ExceptionDestructor(E); // Release memory for the exception } + // __llvm_cxxeh_rethrow - This function turns the top-level caught exception // into an uncaught exception, in preparation for an llvm.unwind, which should // follow immediately after the call to this function. This function must be // prepared to deal with foreign exceptions. // -void __llvm_cxxeh_rethrow(void) { +void __llvm_cxxeh_rethrow() throw() { llvm_exception *E = CaughtExceptionStack; - if (E == 0) { + if (E == 0) // 15.1.8 - If there are no uncaught exceptions being thrown, 'throw;' // should call terminate. // - assert(0 && "FIXME: this should call E->Terminate!"); // FIXME! - } + __terminate(__terminate_handler); // Otherwise we have an exception to rethrow. Move it back to the uncaught // stack. @@ -229,3 +237,115 @@ // Return to the caller, which should perform the unwind now. } +static bool ExceptionSpecificationPermitsException(llvm_exception *E, + const std::type_info *Info, + va_list Args) { + // The only way it could match one of the types is if it is a C++ exception. + if (E->ExceptionType != CXXException) return false; + + llvm_cxx_exception *Ex = get_cxx_exception(E); + + // Scan the list of accepted types, checking to see if the uncaught + // exception is any of them. + do { + // Check to see if the exception matches one of the types allowed by the + // exception specification. If so, return to the caller to have the + // exception rethrown. + if (CXXExceptionISA(Ex, Info)) + return true; + + Info = va_arg(Args, std::type_info *); + } while (Info); + return false; +} + + +// __llvm_cxxeh_check_eh_spec - If a function with an exception specification is +// throwing an exception, this function gets called with the list of type_info +// objects that it is allowing to propagate. Check to see if the current +// uncaught exception is one of these types, and if so, allow it to be thrown by +// returning to the caller, which should immediately follow this call with +// llvm.unwind. +// +// Note that this function does not throw any exceptions, but we can't put an +// exception specification on it or else we'll get infinite loops! +// +void __llvm_cxxeh_check_eh_spec(void *Info, ...) { + const std::type_info *TypeInfo = (const std::type_info *)Info; + llvm_exception *E = UncaughtExceptionStack; + assert(E && "No uncaught exceptions!"); + + if (TypeInfo == 0) { // Empty exception specification + // Whatever exception this is, it is not allowed by the (empty) spec, call + // unexpected, according to 15.4.8. + try { + __llvm_cxxeh_begin_catch(); // Start the catch + __llvm_cxxeh_end_catch(); // Free the exception + __unexpected(__unexpected_handler); + } catch (...) { + // Any exception thrown by unexpected cannot match the ehspec. Call + // terminate, according to 15.4.9. + __terminate(__terminate_handler); + } + } + + // Check to see if the exception matches one of the types allowed by the + // exception specification. If so, return to the caller to have the + // exception rethrown. + + va_list Args; + va_start(Args, Info); + bool Ok = ExceptionSpecificationPermitsException(E, TypeInfo, Args); + va_end(Args); + if (Ok) return; + + // Ok, now we know that the exception is either not a C++ exception (thus not + // permitted to pass through) or not a C++ exception that is allowed. Kill + // the exception and call the unexpected handler. + try { + __llvm_cxxeh_begin_catch(); // Start the catch + __llvm_cxxeh_end_catch(); // Free the exception + } catch (...) { + __terminate(__terminate_handler); // Exception dtor threw + } + + try { + __unexpected(__unexpected_handler); + } catch (...) { + // If the unexpected handler threw an exception, we will get here. Since + // entering the try block calls ..._begin_catch, we need to "rethrow" the + // exception to make it uncaught again. Exiting the catch will then leave + // it in the uncaught state. + __llvm_cxxeh_rethrow(); + } + + // Grab the newly caught exception. If this exception is permitted by the + // specification, allow it to be thrown. + E = UncaughtExceptionStack; + assert(E && "No uncaught exceptions!"); + + va_start(Args, Info); + Ok = ExceptionSpecificationPermitsException(E, TypeInfo, Args); + va_end(Args); + if (Ok) return; + + // Final case, check to see if we can throw an std::bad_exception. + try { + throw std::bad_exception(); + } catch (...) { + __llvm_cxxeh_rethrow(); + } + + // Grab the new bad_exception... + E = UncaughtExceptionStack; + assert(E && "No uncaught exceptions!"); + + // If it's permitted, allow it to be thrown instead. + va_start(Args, Info); + Ok = ExceptionSpecificationPermitsException(E, TypeInfo, Args); + va_end(Args); + if (Ok) return; + + // Otherwise, we are out of options, terminate, according to 15.5.2.2. + __terminate(__terminate_handler); +} From lattner at cs.uiuc.edu Thu Aug 28 09:36:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 09:36:01 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libc/string.c Message-ID: <200308281435.JAA23909@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libc: string.c updated: 1.4 -> 1.5 --- Log message: Squelch warning --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libc/string.c diff -u llvm/runtime/GCCLibraries/libc/string.c:1.4 llvm/runtime/GCCLibraries/libc/string.c:1.5 --- llvm/runtime/GCCLibraries/libc/string.c:1.4 Tue Feb 18 14:42:15 2003 +++ llvm/runtime/GCCLibraries/libc/string.c Thu Aug 28 09:35:12 2003 @@ -5,6 +5,7 @@ //===----------------------------------------------------------------------===// #include +#include void *malloc(size_t); void free(void *); From lattner at cs.uiuc.edu Thu Aug 28 09:37:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 09:37:01 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/c++-exception.cpp c++-exception.h Message-ID: <200308281436.JAA23923@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: c++-exception.cpp updated: 1.4 -> 1.5 c++-exception.h updated: 1.4 -> 1.5 --- Log message: New wrapper around the terminate call. --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/c++-exception.cpp diff -u llvm/runtime/GCCLibraries/libexception/c++-exception.cpp:1.4 llvm/runtime/GCCLibraries/libexception/c++-exception.cpp:1.5 --- llvm/runtime/GCCLibraries/libexception/c++-exception.cpp:1.4 Wed Aug 27 18:00:11 2003 +++ llvm/runtime/GCCLibraries/libexception/c++-exception.cpp Thu Aug 28 09:35:52 2003 @@ -214,6 +214,10 @@ E->ExceptionDestructor(E); // Release memory for the exception } +void __llvm_cxxeh_call_terminate() throw() { + __terminate(__terminate_handler); +} + // __llvm_cxxeh_rethrow - This function turns the top-level caught exception // into an uncaught exception, in preparation for an llvm.unwind, which should Index: llvm/runtime/GCCLibraries/libexception/c++-exception.h diff -u llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.4 llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.5 --- llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.4 Wed Aug 27 17:59:15 2003 +++ llvm/runtime/GCCLibraries/libexception/c++-exception.h Thu Aug 28 09:35:52 2003 @@ -69,6 +69,7 @@ void __llvm_cxxeh_throw(void *ObjectPtr, void *TypeInfoPtr, void (*DtorPtr)(void*)) throw(); + void __llvm_cxxeh_call_terminate() throw() __attribute__((noreturn)); void * __llvm_cxxeh_current_uncaught_exception_isa(void *Ty) throw(); void *__llvm_cxxeh_begin_catch() throw(); From lattner at cs.uiuc.edu Thu Aug 28 09:44:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 09:44:01 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/c++-exception.h Message-ID: <200308281443.JAA24239@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: c++-exception.h updated: 1.5 -> 1.6 --- Log message: Convert C comments to C++ --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/c++-exception.h diff -u llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.5 llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.6 --- llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.5 Thu Aug 28 09:35:52 2003 +++ llvm/runtime/GCCLibraries/libexception/c++-exception.h Thu Aug 28 09:43:36 2003 @@ -13,35 +13,35 @@ #include struct llvm_cxx_exception { - /* TypeInfo - A pointer to the C++ std::type_info object for this exception - * class. This is required because the class may not be polymorphic. - */ + // TypeInfo - A pointer to the C++ std::type_info object for this exception + // class. This is required because the class may not be polymorphic. + // const std::type_info *TypeInfo; - /* ExceptionObjectDestructor - A pointer to the function which destroys the - * object represented by this exception. This is required because the class - * may not be polymorphic. This may be null if there is no cleanup required. - */ + // ExceptionObjectDestructor - A pointer to the function which destroys the + // object represented by this exception. This is required because the class + // may not be polymorphic. This may be null if there is no cleanup required. + // void (*ExceptionObjectDestructor)(void *); - /* UnexpectedHandler - This contains a pointer to the "unexpected" handler - * which may be registered by the user program with set_unexpected. Calls to - * unexpected which are a result of an exception throw are supposed to use the - * value of the handler at the time of the throw, not the currently set value. - */ + // UnexpectedHandler - This contains a pointer to the "unexpected" handler + // which may be registered by the user program with set_unexpected. Calls to + // unexpected which are a result of an exception throw are supposed to use the + // value of the handler at the time of the throw, not the currently set value. + // void (*UnexpectedHandler)(); - /* TerminateHandler - This contains a pointer to the "terminate" handler which - * may be registered by the user program with set_terminate. Calls to - * unexpected which are a result of an exception throw are supposed to use the - * value of the handler at the time of the throw, not the currently set value. - */ + // TerminateHandler - This contains a pointer to the "terminate" handler which + // may be registered by the user program with set_terminate. Calls to + // unexpected which are a result of an exception throw are supposed to use the + // value of the handler at the time of the throw, not the currently set value. + // void (*TerminateHandler)(); - /* BaseException - The language independent portion of the exception state. - * This is at the end of the record so that we can add additional members to - * this structure without breaking binary compatibility. - */ + // BaseException - The language independent portion of the exception state. + // This is at the end of the record so that we can add additional members to + // this structure without breaking binary compatibility. + // llvm_exception BaseException; }; From tbrethou at niobe.cs.uiuc.edu Thu Aug 28 10:22:01 2003 From: tbrethou at niobe.cs.uiuc.edu (Tanya Brethour) Date: Thu Aug 28 10:22:01 2003 Subject: [llvm-commits] CVS: llvm/tools/llvm-ar/ Message-ID: <200308281521.h7SFLT312886@niobe.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ar: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/tools/llvm-ar added to the repository --- Diffs of the changes: From tbrethou at niobe.cs.uiuc.edu Thu Aug 28 10:23:01 2003 From: tbrethou at niobe.cs.uiuc.edu (Tanya Brethour) Date: Thu Aug 28 10:23:01 2003 Subject: [llvm-commits] CVS: llvm/tools/llvm-ar/llvm-ar.cpp Makefile Message-ID: <200308281522.h7SFMmG12997@niobe.cs.uiuc.edu> Changes in directory llvm/tools/llvm-ar: llvm-ar.cpp added (r1.1) Makefile added (r1.1) --- Log message: First version of llvm-ar added to cvs repository. --- Diffs of the changes: Index: llvm/tools/llvm-ar/llvm-ar.cpp diff -c /dev/null llvm/tools/llvm-ar/llvm-ar.cpp:1.1 *** /dev/null Thu Aug 28 10:22:48 2003 --- llvm/tools/llvm-ar/llvm-ar.cpp Thu Aug 28 10:22:38 2003 *************** *** 0 **** --- 1,373 ---- + //===----------------------------------------------------------------------===// + // LLVM 'ar' UTILITY + // + // This utility may be invoked in the following manner: + // llvm-ar archivename files.. + // + //===----------------------------------------------------------------------===// + #include "Support/CommandLine.h" + #include "llvm/Bytecode/Reader.h" + #include "llvm/Module.h" + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + + using std::string; + using std::vector; + using std::cout; + + + #define ARFMAG "\n" /* header trailer string */ + #define ARMAG "!\n" /* magic string */ + #define SARMAG 8 /* length of magic string */ + + namespace { + + // Each file member is preceded by a file member header. Which is + // of the following format: + // + // char ar_name[16] - '/' terminated file member name. + // If the file name does not fit, a dummy name is used. + // char ar_date[12] - file date in decimal + // char ar_uid[6] - User id of file owner in decimal. + // char ar_gid[6] - Group ID file belongs to in decimal. + // char ar_mode[8] - File mode in octal. + // char ar_size[10] - Size of file in decimal. + // char ar_fmag[2] - Trailer of header file, a newline. + struct ar_hdr { + char name[16]; + char date[12]; + char uid[6]; + char gid[6]; + char mode[8]; + char size[10]; + char fmag[2]; + void init() { + memset(name,' ',16); + memset(date,' ',12); + memset(uid,' ',6); + memset(gid,' ',6); + memset(mode,' ',8); + memset(size,' ',10); + memset(fmag,' ',2); + } + }; + } + + //Option to generate symbol table or not + //running llvm-ar -s is the same as ranlib + cl::opt SymbolTable ("s", cl::desc("Generate an archive symbol table")); + + //Archive name + cl::opt Archive (cl::Positional, cl::desc(""), + cl::Required); + + //For now we require one or more member files, this should change so + //we can just run llvm-ar -s on an archive to generate the symbol + //table + cl::list Members(cl::ConsumeAfter, cl::desc("...")); + + + static inline bool Error(std::string *ErrorStr, const char *Message) { + if (ErrorStr) *ErrorStr = Message; + return true; + } + + + // WriteSymbolTable - Writes symbol table to ArchiveFile, return false + // on errors. Also returns by reference size of symbol table. + // + // Overview of method: + // 1) Generate the header for the symbol table. This is a normal + // archive member header, but it has a zero length name. + // 2) For each archive member file, stat the file and parse the bytecode + // Store cummulative offset (file size + header size). + // 3) Loop over all the symbols for the current member file, + // add offset entry to offset vector, and add symbol name to its vector. + // Note: The symbol name vector is a vector of chars to speed up calculating + // the total size of the symbol table. + // 4) Update offset vector once we know the total size of symbol table. This is + // because the symbol table appears before all archive member file contents. + // We add the size of magic string, and size of symbol table to each offset. + // 5) If the new updated offset it not even, we add 1 byte to offset because + // a newline will be inserted when writing member files. This adjustment is + // cummulative (ie. each time we have an odd offset we add 1 to total adjustment). + // 6) Lastly, write symbol table to file. + // + bool WriteSymbolTable(std::ofstream &ArchiveFile) { + + //Create header for symbol table. This is essentially an empty header with the + //name set to a '/' to indicate its a symbol table. + ar_hdr Hdr; + Hdr.init(); + + //Name of symbol table is '/' + Hdr.name[0] = '/'; + Hdr.name[1] = '/0'; + + //Set the header trailer to a newline + memcpy(Hdr.fmag,ARFMAG,sizeof(ARFMAG)); + + + //Write header to archive file + ArchiveFile.write((char*)&Hdr, sizeof(Hdr)); + + + unsigned memoff = 0; //Keep Track of total size of files added to archive + vector offsets; //Vector of offsets into archive file + vector names; //Vector of characters that are the symbol names. + + //Loop over archive member files, parse bytecode, and generate symbol table. + for(unsigned i=0; ibegin(), E=M->end(); I != E; ++I) { + + //get function name + string NM = ((Function*)I)->getName(); + + //Loop over the characters in the name and add to symbol name vector + for(unsigned i=0; i> 24) & 255; + num[1] = (temp >> 16) & 255; + num[2] = (temp >> 8) & 255; + num[3] = temp & 255; + + //Write number of symbols to archive file + ArchiveFile.write(num,4); + + //Adjustment to offset to start files on even byte boundaries + unsigned adjust = 0; + + //Update offsets write symbol tabel to archive. + for(unsigned i=0; i> 24) & 255; + output[1] = (offsets[i] >> 16) & 255; + output[2] = (offsets[i] >> 8) & 255; + output[3] = offsets[i] & 255; + ArchiveFile.write(output,4); + } + + + //Write out symbol name vector. + for(unsigned i=0; i Changes in directory llvm/include/llvm/CodeGen: SchedGraphCommon.h updated: 1.3 -> 1.4 --- Log message: Moved index in BB to common graph class. --- Diffs of the changes: Index: llvm/include/llvm/CodeGen/SchedGraphCommon.h diff -u llvm/include/llvm/CodeGen/SchedGraphCommon.h:1.3 llvm/include/llvm/CodeGen/SchedGraphCommon.h:1.4 --- llvm/include/llvm/CodeGen/SchedGraphCommon.h:1.3 Wed Aug 27 10:52:23 2003 +++ llvm/include/llvm/CodeGen/SchedGraphCommon.h Thu Aug 28 10:31:28 2003 @@ -29,6 +29,7 @@ std::vector inEdges; std::vector outEdges; int latency; + int origIndexInBB; // original position of instr in BB public: typedef std::vector::iterator iterator; @@ -41,7 +42,7 @@ int getLatency() const { return latency; } unsigned getNumInEdges() const { return inEdges.size(); } unsigned getNumOutEdges() const { return outEdges.size(); } - + int getOrigIndexInBB() const { return origIndexInBB; } // Iterators iterator beginInEdges() { return inEdges.begin(); } @@ -68,7 +69,8 @@ // disable default constructor and provide a ctor for single-block graphs SchedGraphNodeCommon(); // DO NOT IMPLEMENT - inline SchedGraphNodeCommon(unsigned Id) : ID(Id), latency(0) {} + inline SchedGraphNodeCommon(unsigned Id, int index) : ID(Id), latency(0), + origIndexInBB(index) {} virtual ~SchedGraphNodeCommon(); //Functions to add and remove edges From tbrethou at cs.uiuc.edu Thu Aug 28 10:32:05 2003 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Thu Aug 28 10:32:05 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/InstrSched/SchedGraph.cpp SchedGraph.h Message-ID: <200308281530.KAA21485@tank.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/InstrSched: SchedGraph.cpp updated: 1.48 -> 1.49 SchedGraph.h updated: 1.33 -> 1.34 --- Log message: Moved index into BB to common graph class because its needed by ModuloSchedGraph. --- Diffs of the changes: Index: llvm/lib/CodeGen/InstrSched/SchedGraph.cpp diff -u llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.48 llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.49 --- llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.48 Tue Aug 26 21:42:58 2003 +++ llvm/lib/CodeGen/InstrSched/SchedGraph.cpp Thu Aug 28 10:30:40 2003 @@ -44,8 +44,7 @@ SchedGraphNode::SchedGraphNode(unsigned NID, MachineBasicBlock *mbb, int indexInBB, const TargetMachine& Target) - : SchedGraphNodeCommon(NID), origIndexInBB(indexInBB), MBB(mbb), - MI(mbb ? (*mbb)[indexInBB] : 0) { + : SchedGraphNodeCommon(NID,indexInBB), MBB(mbb), MI(mbb ? (*mbb)[indexInBB] : 0) { if (MI) { MachineOpCode mopCode = MI->getOpCode(); latency = Target.getInstrInfo().hasResultInterlock(mopCode) Index: llvm/lib/CodeGen/InstrSched/SchedGraph.h diff -u llvm/lib/CodeGen/InstrSched/SchedGraph.h:1.33 llvm/lib/CodeGen/InstrSched/SchedGraph.h:1.34 --- llvm/lib/CodeGen/InstrSched/SchedGraph.h:1.33 Wed Aug 27 10:12:24 2003 +++ llvm/lib/CodeGen/InstrSched/SchedGraph.h Thu Aug 28 10:30:40 2003 @@ -26,7 +26,6 @@ class SchedGraphNode : public SchedGraphNodeCommon { - int origIndexInBB; // original position of machine instr in BB MachineBasicBlock *MBB; const MachineInstr *MI; @@ -46,7 +45,6 @@ bool isDummyNode() const { return (MI == NULL); } MachineBasicBlock &getMachineBasicBlock() const { return *MBB; } - int getOrigIndexInBB() const { return origIndexInBB; } void print(std::ostream &os) const; }; From lattner at cs.uiuc.edu Thu Aug 28 10:51:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 10:51:02 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/TEST.nightly.report Message-ID: <200308281550.KAA19719@neo.cs.uiuc.edu> Changes in directory llvm/test/Programs: TEST.nightly.report updated: 1.13 -> 1.14 --- Log message: Add support for the funny sparc syntax for time --- Diffs of the changes: Index: llvm/test/Programs/TEST.nightly.report diff -u llvm/test/Programs/TEST.nightly.report:1.13 llvm/test/Programs/TEST.nightly.report:1.14 --- llvm/test/Programs/TEST.nightly.report:1.13 Mon Aug 18 10:19:13 2003 +++ llvm/test/Programs/TEST.nightly.report Thu Aug 28 10:50:29 2003 @@ -12,7 +12,7 @@ # FormatTime - Convert a time from 1m23.45 into 83.45 sub FormatTime { my $Time = shift; - if ($Time =~ m/([0-9]+)m([0-9.]+)/) { + if ($Time =~ m/([0-9]+)[m:]([0-9.]+)/) { $Time = sprintf("%7.4f", $1*60.0+$2); } return $Time; From lattner at cs.uiuc.edu Thu Aug 28 11:26:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 11:26:01 2003 Subject: [llvm-commits] CVS: llvm/tools/link/link.cpp Message-ID: <200308281625.LAA27205@apoc.cs.uiuc.edu> Changes in directory llvm/tools/link: link.cpp updated: 1.26 -> 1.27 --- Log message: Reorder #includes Make sure that we veryify the result before writing it out! --- Diffs of the changes: Index: llvm/tools/link/link.cpp diff -u llvm/tools/link/link.cpp:1.26 llvm/tools/link/link.cpp:1.27 --- llvm/tools/link/link.cpp:1.26 Fri Jun 13 11:10:26 2003 +++ llvm/tools/link/link.cpp Thu Aug 28 11:25:34 2003 @@ -6,10 +6,11 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Utils/Linker.h" +#include "llvm/Module.h" +#include "llvm/Analysis/Verifier.h" #include "llvm/Bytecode/Reader.h" #include "llvm/Bytecode/Writer.h" -#include "llvm/Module.h" +#include "llvm/Transforms/Utils/Linker.h" #include "Support/CommandLine.h" #include "Support/Signals.h" #include @@ -123,6 +124,11 @@ // Make sure that the Out file gets unlink'd from the disk if we get a // SIGINT RemoveFileOnSignal(OutputFilename); + } + + if (verifyModule(*Composite.get())) { + std::cerr << argv[0] << ": linked module is broken!\n"; + return 1; } if (Verbose) std::cerr << "Writing bytecode...\n"; From lattner at cs.uiuc.edu Thu Aug 28 11:44:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 11:44:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/Linker.cpp Message-ID: <200308281643.LAA27842@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: Linker.cpp updated: 1.53 -> 1.54 --- Log message: Fix bug where we considered function types equivalent even if they had differing numbers of arguments --- Diffs of the changes: Index: llvm/lib/Transforms/Utils/Linker.cpp diff -u llvm/lib/Transforms/Utils/Linker.cpp:1.53 llvm/lib/Transforms/Utils/Linker.cpp:1.54 --- llvm/lib/Transforms/Utils/Linker.cpp:1.53 Sun Aug 24 14:30:20 2003 +++ llvm/lib/Transforms/Utils/Linker.cpp Thu Aug 28 11:42:50 2003 @@ -79,7 +79,9 @@ switch (DestTyT->getPrimitiveID()) { case Type::FunctionTyID: { if (cast(DestTyT)->isVarArg() != - cast(SrcTyT)->isVarArg()) + cast(SrcTyT)->isVarArg() || + cast(DestTyT)->getNumContainedTypes() != + cast(SrcTyT)->getNumContainedTypes()) return true; for (unsigned i = 0, e = getFT(DestTy)->getNumContainedTypes(); i != e; ++i) if (RecursiveResolveTypesI(getFT(DestTy)->getContainedType(i), From tbrethou at cs.uiuc.edu Thu Aug 28 12:13:03 2003 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Thu Aug 28 12:13:03 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.cpp ModuloSchedGraph.h ModuloScheduling.cpp ModuloScheduling.h Message-ID: <200308281712.MAA24529@tank.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/ModuloScheduling: ModuloSchedGraph.cpp updated: 1.10 -> 1.11 ModuloSchedGraph.h updated: 1.9 -> 1.10 ModuloScheduling.cpp updated: 1.10 -> 1.11 ModuloScheduling.h (r1.9) removed --- Log message: Putting my revised version of ModuloScheduling in cvs. This is not complete... --- Diffs of the changes: Index: llvm/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.cpp diff -u llvm/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.cpp:1.10 llvm/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.cpp:1.11 --- llvm/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.cpp:1.10 Thu Aug 21 17:05:57 2003 +++ llvm/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.cpp Thu Aug 28 12:12:14 2003 @@ -1,1507 +1,130 @@ -//===- ModuloSchedGraph.cpp - Graph datastructure for Modulo Scheduling ---===// -// -// +//===- ModuloSchedGraph.cpp - Modulo Scheduling Graph and Set -*- C++ -*---===// +// +// Description here //===----------------------------------------------------------------------===// -#include "llvm/CodeGen/InstrSelection.h" -#include "llvm/Function.h" -#include "llvm/Instructions.h" -#include "llvm/Type.h" -#include "llvm/CodeGen/MachineCodeForInstruction.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/Target/TargetSchedInfo.h" -#include "Support/StringExtras.h" -#include "Support/STLExtras.h" -#include "Support/hash_map" -#include "Support/Statistic.h" -#include "ModuloScheduling.h" #include "ModuloSchedGraph.h" -#include -#include -#include -#include - - -#define UNIDELAY 1 - -using std::cerr; -using std::endl; -using std::vector; - - -/***********member functions for ModuloSchedGraphNode*********/ - - -ModuloSchedGraphNode::ModuloSchedGraphNode(unsigned int in_nodeId, - const BasicBlock * in_bb, - const Instruction * in_inst, - int indexInBB, - const TargetMachine & target) - :SchedGraphNodeCommon(in_nodeId, indexInBB), inst(in_inst){ - - if (inst) { - //FIXME: find the latency - //currently set the latency to zero - latency = 0; - } -} - - -/***********member functions for ModuloSchedGraph*********/ - -void -ModuloSchedGraph::addDefUseEdges(const BasicBlock *bb){ - - //collect def instructions, store them in vector - const TargetInstrInfo & mii = target.getInstrInfo(); - vector < ModuloSchedGraphNode * > defVec; - - - //find those def instructions - for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E; ++I) { - if (I->getType() != Type::VoidTy) { - defVec.push_back(this->getGraphNodeForInst(I)); - } - } - - for (unsigned int i = 0; i < defVec.size(); i++) { - for (Value::use_const_iterator I = defVec[i]->getInst()->use_begin(); - I != defVec[i]->getInst()->use_end(); I++) { - //for each use of a def, add a flow edge from the def instruction to the - //ref instruction - - const Instruction *value = defVec[i]->getInst(); - Instruction *inst = (Instruction *) (*I); - ModuloSchedGraphNode *node = NULL; - - for (BasicBlock::const_iterator ins = bb->begin(), E = bb->end(); - ins != E; ++ins) - if ((const Instruction *) ins == inst) { - node = (*this)[inst]; - break; - } - - - if (node == NULL){ - - //inst is not an instruction in this block - //do nothing - - } else { - // Add a flow edge from the def instruction to the ref instruction - // This is a true dependence, so the delay is equal to the - //delay of the preceding node. - - int delay = 0; - - // self loop will not happen in SSA form - assert(defVec[i] != node && "same node?"); - - MachineCodeForInstruction & tempMvec = - MachineCodeForInstruction::get(value); - for (unsigned j = 0; j < tempMvec.size(); j++) { - MachineInstr *temp = tempMvec[j]; - delay = std::max(delay, mii.minLatency(temp->getOpCode())); - } - - SchedGraphEdge *trueEdge = - new SchedGraphEdge(defVec[i], node, value, - SchedGraphEdge::TrueDep, delay); - - // if the ref instruction is before the def instrution - // then the def instruction must be a phi instruction - // add an anti-dependence edge to from the ref instruction to the def - // instruction - if (node->getOrigIndexInBB() < defVec[i]->getOrigIndexInBB()) { - assert(PHINode::classof(inst) - && "the ref instruction befre def is not PHINode?"); - trueEdge->setIteDiff(1); - } - - } - - } - } -} - -void -ModuloSchedGraph::addCDEdges(const BasicBlock * bb) { - - // find the last instruction in the basic block - // see if it is an branch instruction. - // If yes, then add an edge from each node expcept the last node - // to the last node - - const Instruction *inst = &(bb->back()); - ModuloSchedGraphNode *lastNode = (*this)[inst]; - if (TerminatorInst::classof(inst)) - for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E; - I++) { - if (inst != I) { - ModuloSchedGraphNode *node = (*this)[I]; - //use latency of 0 - (void) new SchedGraphEdge(node, lastNode, SchedGraphEdge::CtrlDep, - SchedGraphEdge::NonDataDep, 0); - } - - } -} - -static const int SG_LOAD_REF = 0; -static const int SG_STORE_REF = 1; -static const int SG_CALL_REF = 2; - -static const unsigned int SG_DepOrderArray[][3] = { - {SchedGraphEdge::NonDataDep, - SchedGraphEdge::AntiDep, - SchedGraphEdge::AntiDep}, - {SchedGraphEdge::TrueDep, - SchedGraphEdge::OutputDep, - SchedGraphEdge::TrueDep | SchedGraphEdge::OutputDep}, - {SchedGraphEdge::TrueDep, - SchedGraphEdge::AntiDep | SchedGraphEdge::OutputDep, - SchedGraphEdge::TrueDep | SchedGraphEdge::AntiDep - | SchedGraphEdge::OutputDep} -}; - - -// Add a dependence edge between every pair of machine load/store/call -// instructions, where at least one is a store or a call. -// Use latency 1 just to ensure that memory operations are ordered; -// latency does not otherwise matter (true dependences enforce that). -// -void -ModuloSchedGraph::addMemEdges(const BasicBlock * bb) { - - vector memNodeVec; - - //construct the memNodeVec - for (BasicBlock::const_iterator I = bb->begin(), - E = bb->end(); I != E; ++I) { - - if (LoadInst::classof(I) || StoreInst::classof(I) - || CallInst::classof(I)) { - - ModuloSchedGraphNode *node = (*this)[(const Instruction *) I]; - memNodeVec.push_back(node); - - } - } - - // Instructions in memNodeVec are in execution order within the - // basic block, so simply look at all pairs - // i]>. - - for (unsigned im = 0, NM = memNodeVec.size(); im < NM; im++) { - - const Instruction *fromInst,*toInst; - int toType, fromType; - - //get the first mem instruction and instruction type - fromInst = memNodeVec[im]->getInst(); - fromType = CallInst::classof(fromInst) ? SG_CALL_REF - : LoadInst::classof(fromInst) ? SG_LOAD_REF : SG_STORE_REF; - - for (unsigned jm = im + 1; jm < NM; jm++) { - - //get the second mem instruction and instruction type - toInst = memNodeVec[jm]->getInst(); - toType = CallInst::classof(toInst) ? SG_CALL_REF - : LoadInst::classof(toInst) ? SG_LOAD_REF : SG_STORE_REF; - - //add two edges if not both of them are LOAD instructions - if (fromType != SG_LOAD_REF || toType != SG_LOAD_REF) { - (void) new SchedGraphEdge(memNodeVec[im], memNodeVec[jm], - SchedGraphEdge::MemoryDep, - SG_DepOrderArray[fromType][toType], 1); - - SchedGraphEdge *edge = - new SchedGraphEdge(memNodeVec[jm], memNodeVec[im], - SchedGraphEdge::MemoryDep, - SG_DepOrderArray[toType][fromType], 1); - - //set the iteration difference for this edge to 1. - edge->setIteDiff(1); - - } - } - } -} - -/* - this function build graph nodes for each instruction - in the basicblock -*/ - -void -ModuloSchedGraph::buildNodesforBB(const TargetMachine &target, - const BasicBlock *bb){ - - int i = 0; - ModuloSchedGraphNode *node; - - for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); - I != E; ++I) { - - node=new ModuloSchedGraphNode(getNumNodes(), bb, I, i, target); - - i++; - - this->addHash(I, node); - } - -} - - -/* - determine if this basicblock includes a loop or not -*/ - -bool -ModuloSchedGraph::isLoop(const BasicBlock *bb) { - - //only if the last instruction in the basicblock is branch instruction and - //there is at least an option to branch itself - - const Instruction *inst = &(bb->back()); - - if (BranchInst::classof(inst)) { - for (unsigned i = 0; i < ((BranchInst *) inst)->getNumSuccessors(); - i++) { - BasicBlock *sb = ((BranchInst *) inst)->getSuccessor(i); - if (sb == bb) - return true; - } - } - - return false; - -} - -/* - compute every node's ASAP - -*/ - -//FIXME: now assume the only backward edges come from the edges from other -//nodes to the phi Node so i will ignore all edges to the phi node; after -//this, there shall be no recurrence. - -void -ModuloSchedGraph::computeNodeASAP(const BasicBlock *bb) { - - - unsigned numNodes = bb->size(); - for (unsigned i = 2; i < numNodes + 2; i++) { - ModuloSchedGraphNode *node = getNode(i); - node->setPropertyComputed(false); - } - - for (unsigned i = 2; i < numNodes + 2; i++) { - ModuloSchedGraphNode *node = getNode(i); - node->ASAP = 0; - if (i == 2 || node->getNumInEdges() == 0) { - node->setPropertyComputed(true); - continue; - } - for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E = - node->endInEdges(); I != E; I++) { - SchedGraphEdge *edge = *I; - ModuloSchedGraphNode *pred = - (ModuloSchedGraphNode *) (edge->getSrc()); - assert(pred->getPropertyComputed() - && "pred node property is not computed!"); - int temp = - pred->ASAP + edge->getMinDelay() - - edge->getIteDiff() * this->MII; - node->ASAP = std::max(node->ASAP, temp); - } - node->setPropertyComputed(true); - } -} - - -/* - compute every node's ALAP in the basic block -*/ - -void -ModuloSchedGraph::computeNodeALAP(const BasicBlock *bb) { - - unsigned numNodes = bb->size(); - int maxASAP = 0; - for (unsigned i = numNodes + 1; i >= 2; i--) { - - ModuloSchedGraphNode *node = getNode(i); - node->setPropertyComputed(false); - maxASAP = std::max(maxASAP, node->ASAP); - - } - - for (unsigned i = numNodes + 1; i >= 2; i--) { - ModuloSchedGraphNode *node = getNode(i); - - node->ALAP = maxASAP; - - for (ModuloSchedGraphNode::const_iterator I = - node->beginOutEdges(), E = node->endOutEdges(); I != E; I++) { - - SchedGraphEdge *edge = *I; - ModuloSchedGraphNode *succ = - (ModuloSchedGraphNode *) (edge->getSink()); - if (PHINode::classof(succ->getInst())) - continue; - - assert(succ->getPropertyComputed() - && "succ node property is not computed!"); - - int temp = - succ->ALAP - edge->getMinDelay() + - edge->getIteDiff() * this->MII; - - node->ALAP = std::min(node->ALAP, temp); - - } - node->setPropertyComputed(true); - } -} - -/* - compute every node's mov in this basicblock -*/ - -void -ModuloSchedGraph::computeNodeMov(const BasicBlock *bb){ - - unsigned numNodes = bb->size(); - for (unsigned i = 2; i < numNodes + 2; i++) { - - ModuloSchedGraphNode *node = getNode(i); - node->mov = node->ALAP - node->ASAP; - assert(node->mov >= 0 - && "move freedom for this node is less than zero? "); - - } - -} - - -/* - compute every node's depth in this basicblock -*/ -void -ModuloSchedGraph::computeNodeDepth(const BasicBlock * bb){ - - unsigned numNodes = bb->size(); - - for (unsigned i = 2; i < numNodes + 2; i++) { - - ModuloSchedGraphNode *node = getNode(i); - node->setPropertyComputed(false); - - } - - for (unsigned i = 2; i < numNodes + 2; i++) { - - ModuloSchedGraphNode *node = getNode(i); - node->depth = 0; - if (i == 2 || node->getNumInEdges() == 0) { - node->setPropertyComputed(true); - continue; - } - - for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E = - node->endInEdges(); I != E; I++) { - SchedGraphEdge *edge = *I; - ModuloSchedGraphNode *pred = - (ModuloSchedGraphNode *) (edge->getSrc()); - assert(pred->getPropertyComputed() - && "pred node property is not computed!"); - int temp = pred->depth + edge->getMinDelay(); - node->depth = std::max(node->depth, temp); - } - node->setPropertyComputed(true); - - } - -} - - -/* - compute every node's height in this basic block -*/ - -void -ModuloSchedGraph::computeNodeHeight(const BasicBlock *bb){ - - unsigned numNodes = bb->size(); - for (unsigned i = numNodes + 1; i >= 2; i--) { - ModuloSchedGraphNode *node = getNode(i); - node->setPropertyComputed(false); - } - - for (unsigned i = numNodes + 1; i >= 2; i--) { - ModuloSchedGraphNode *node = getNode(i); - node->height = 0; - for (ModuloSchedGraphNode::const_iterator I = - node->beginOutEdges(), E = node->endOutEdges(); I != E; ++I) { - SchedGraphEdge *edge = *I; - ModuloSchedGraphNode *succ = - (ModuloSchedGraphNode *) (edge->getSink()); - if (PHINode::classof(succ->getInst())) - continue; - assert(succ->getPropertyComputed() - && "succ node property is not computed!"); - node->height = std::max(node->height, succ->height + edge->getMinDelay()); - - } - node->setPropertyComputed(true); - } - -} - -/* - compute every node's property in a basicblock -*/ - -void ModuloSchedGraph::computeNodeProperty(const BasicBlock * bb) -{ - //FIXME: now assume the only backward edges come from the edges from other - //nodes to the phi Node so i will ignore all edges to the phi node; after - //this, there shall be no recurrence. - - this->computeNodeASAP(bb); - this->computeNodeALAP(bb); - this->computeNodeMov(bb); - this->computeNodeDepth(bb); - this->computeNodeHeight(bb); -} - - -/* - compute the preset of this set without considering the edges - between backEdgeSrc and backEdgeSink -*/ -std::vector -ModuloSchedGraph::predSet(std::vector set, - unsigned backEdgeSrc, - unsigned - backEdgeSink){ - - std::vector predS; - - for (unsigned i = 0; i < set.size(); i++) { - - ModuloSchedGraphNode *node = set[i]; - for (ModuloSchedGraphNode::const_iterator I = node->beginInEdges(), E = - node->endInEdges(); I != E; I++) { - SchedGraphEdge *edge = *I; - - //if edges between backEdgeSrc and backEdgeSink, omitted - if (edge->getSrc()->getNodeId() == backEdgeSrc - && edge->getSink()->getNodeId() == backEdgeSink) - continue; - ModuloSchedGraphNode *pred = - (ModuloSchedGraphNode *) (edge->getSrc()); - - //if pred is not in the predSet .... - bool alreadyInset = false; - for (unsigned j = 0; j < predS.size(); ++j) - if (predS[j]->getNodeId() == pred->getNodeId()) { - alreadyInset = true; - break; - } - - // and pred is not in the set .... - for (unsigned j = 0; j < set.size(); ++j) - if (set[j]->getNodeId() == pred->getNodeId()) { - alreadyInset = true; - break; - } - - //push it into the predS - if (!alreadyInset) - predS.push_back(pred); - } - } - return predS; -} - - -/* - return pred set to this set -*/ - -ModuloSchedGraph::NodeVec -ModuloSchedGraph::predSet(NodeVec set){ - - //node number increases from 2, - return predSet(set, 0, 0); -} - -/* - return pred set to _node, ignoring - any edge between backEdgeSrc and backEdgeSink -*/ -std::vector -ModuloSchedGraph::predSet(ModuloSchedGraphNode *_node, - unsigned backEdgeSrc, unsigned backEdgeSink){ - - std::vector set; - set.push_back(_node); - return predSet(set, backEdgeSrc, backEdgeSink); -} - - -/* - return pred set to _node, ignoring -*/ - -std::vector -ModuloSchedGraph::predSet(ModuloSchedGraphNode * _node){ - - return predSet(_node, 0, 0); - -} - -/* - return successor set to the input set - ignoring any edge between src and sink -*/ - -std::vector -ModuloSchedGraph::succSet(std::vector set, - unsigned src, unsigned sink){ - - std::vector succS; - - for (unsigned i = 0; i < set.size(); i++) { - ModuloSchedGraphNode *node = set[i]; - for (ModuloSchedGraphNode::const_iterator I = - node->beginOutEdges(), E = node->endOutEdges(); I != E; I++) { - SchedGraphEdge *edge = *I; - - //if the edge is between src and sink, skip - if (edge->getSrc()->getNodeId() == src - && edge->getSink()->getNodeId() == sink) - continue; - ModuloSchedGraphNode *succ = - (ModuloSchedGraphNode *) (edge->getSink()); - - //if pred is not in the successor set .... - bool alreadyInset = false; - for (unsigned j = 0; j < succS.size(); j++) - if (succS[j]->getNodeId() == succ->getNodeId()) { - alreadyInset = true; - break; - } - - //and not in this set .... - for (unsigned j = 0; j < set.size(); j++) - if (set[j]->getNodeId() == succ->getNodeId()) { - alreadyInset = true; - break; - } - - //push it into the successor set - if (!alreadyInset) - succS.push_back(succ); - } - } - return succS; -} - -/* - return successor set to the input set -*/ - -ModuloSchedGraph::NodeVec ModuloSchedGraph::succSet(NodeVec set){ - - return succSet(set, 0, 0); +#include "llvm/Type.h" +ModuloSchedGraphNode::ModuloSchedGraphNode(unsigned id, int index, + const Instruction *inst, + const TargetMachine &targ) + : SchedGraphNodeCommon(id, index), Inst(inst), Target(targ) { } -/* - return successor set to the input node - ignoring any edge between src and sink -*/ - -std::vector -ModuloSchedGraph::succSet(ModuloSchedGraphNode *_node, - unsigned src, unsigned sink){ - - std::vectorset; - - set.push_back(_node); - - return succSet(set, src, sink); - +void ModuloSchedGraphNode::print(std::ostream &os) const { + os << "Modulo Scheduling Node\n"; } -/* - return successor set to the input node -*/ +ModuloSchedGraph::ModuloSchedGraph(const BasicBlock *bb, const TargetMachine &targ) + : SchedGraphCommon(), BB(bb), Target(targ) { -std::vector -ModuloSchedGraph::succSet(ModuloSchedGraphNode * _node){ - - return succSet(_node, 0, 0); - -} + assert(BB != NULL && "Basic Block is null"); + //Builds nodes from each instruction in the basic block + buildNodesForBB(); -/* - find maximum delay between srcId and sinkId -*/ - -SchedGraphEdge* -ModuloSchedGraph::getMaxDelayEdge(unsigned srcId, - unsigned sinkId){ - - ModuloSchedGraphNode *node = getNode(srcId); - SchedGraphEdge *maxDelayEdge = NULL; - int maxDelay = -1; - for (ModuloSchedGraphNode::const_iterator I = node->beginOutEdges(), E = - node->endOutEdges(); I != E; I++) { - SchedGraphEdge *edge = *I; - if (edge->getSink()->getNodeId() == sinkId) - if (edge->getMinDelay() > maxDelay) { - maxDelayEdge = edge; - maxDelay = edge->getMinDelay(); - } - } - assert(maxDelayEdge != NULL && "no edge between the srcId and sinkId?"); - return maxDelayEdge; - } -/* - dump all circuits found -*/ - -void -ModuloSchedGraph::dumpCircuits(){ - - DEBUG_PRINT(std::cerr << "dumping circuits for graph:\n"); - int j = -1; - while (circuits[++j][0] != 0) { - int k = -1; - while (circuits[j][++k] != 0) - DEBUG_PRINT(std::cerr << circuits[j][k] << "\t"); - DEBUG_PRINT(std::cerr << "\n"); +void ModuloSchedGraph::buildNodesForBB() { + int count = 0; + for (BasicBlock::const_iterator i = BB->begin(), e = BB->end(); i != e; ++i) { + addNode(i,new ModuloSchedGraphNode(size(), count, i, Target)); + count++; } -} -/* - dump all sets found -*/ + //Get machine instruction(s) for the llvm instruction + //MachineCodeForInstruction &MC = MachineCodeForInstruction::get(Node->first); + -void -ModuloSchedGraph::dumpSet(std::vector < ModuloSchedGraphNode * >set){ - - for (unsigned i = 0; i < set.size(); i++) - DEBUG_PRINT(std::cerr << set[i]->getNodeId() << "\t"); - DEBUG_PRINT(std::cerr << "\n"); - } -/* - return union of set1 and set2 -*/ - -std::vector -ModuloSchedGraph::vectorUnion(std::vector set1, - std::vector set2){ - - std::vector unionVec; - for (unsigned i = 0; i < set1.size(); i++) - unionVec.push_back(set1[i]); - for (unsigned j = 0; j < set2.size(); j++) { - bool inset = false; - for (unsigned i = 0; i < unionVec.size(); i++) - if (set2[j] == unionVec[i]) - inset = true; - if (!inset) - unionVec.push_back(set2[j]); - } - return unionVec; +void ModuloSchedGraph::addNode(const Instruction *I, + ModuloSchedGraphNode *node) { + assert(node!= NULL && "New ModuloSchedGraphNode is null"); + GraphMap[I] = node; } -/* - return conjuction of set1 and set2 -*/ -std::vector -ModuloSchedGraph::vectorConj(std::vector set1, - std::vector set2){ +void ModuloSchedGraph::addDepEdges() { - std::vector conjVec; - for (unsigned i = 0; i < set1.size(); i++) - for (unsigned j = 0; j < set2.size(); j++) - if (set1[i] == set2[j]) - conjVec.push_back(set1[i]); - return conjVec; - -} - -/* - return the result of subtracting set2 from set1 - (set1 -set2) -*/ -ModuloSchedGraph::NodeVec -ModuloSchedGraph::vectorSub(NodeVec set1, - NodeVec set2){ + //Get Machine target information for calculating delay + const TargetInstrInfo &MTI = Target.getInstrInfo(); - NodeVec newVec; - for (NodeVec::iterator I = set1.begin(); I != set1.end(); I++) { - - bool inset = false; - for (NodeVec::iterator II = set2.begin(); II != set2.end(); II++) - if ((*I)->getNodeId() == (*II)->getNodeId()) { - inset = true; - break; - } - - if (!inset) - newVec.push_back(*I); + //Loop over instruction in BB and gather dependencies + for(BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) { - } - - return newVec; - -} - -/* - order all nodes in the basicblock - based on the sets information and node property - - output: ordered nodes are stored in oNodes -*/ - -void ModuloSchedGraph::orderNodes() { - oNodes.clear(); - - std::vector < ModuloSchedGraphNode * >set; - unsigned numNodes = bb->size(); - - // first order all the sets - int j = -1; - int totalDelay = -1; - int preDelay = -1; - while (circuits[++j][0] != 0) { - int k = -1; - preDelay = totalDelay; - - while (circuits[j][++k] != 0) { - ModuloSchedGraphNode *node = getNode(circuits[j][k]); - unsigned nextNodeId; - nextNodeId = - circuits[j][k + 1] != 0 ? circuits[j][k + 1] : circuits[j][0]; - SchedGraphEdge *edge = getMaxDelayEdge(circuits[j][k], nextNodeId); - totalDelay += edge->getMinDelay(); - } - if (preDelay != -1 && totalDelay > preDelay) { - // swap circuits[j][] and cuicuits[j-1][] - unsigned temp[MAXNODE]; - for (int k = 0; k < MAXNODE; k++) { - temp[k] = circuits[j - 1][k]; - circuits[j - 1][k] = circuits[j][k]; - circuits[j][k] = temp[k]; - } - //restart - j = -1; - } - } - - - // build the first set - int backEdgeSrc; - int backEdgeSink; - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "building the first set" << "\n"); - int setSeq = -1; - int k = -1; - setSeq++; - while (circuits[setSeq][++k] != 0) - set.push_back(getNode(circuits[setSeq][k])); - if (circuits[setSeq][0] != 0) { - backEdgeSrc = circuits[setSeq][k - 1]; - backEdgeSink = circuits[setSeq][0]; - } - if (ModuloScheduling::printScheduleProcess()) { - DEBUG_PRINT(std::cerr << "the first set is:"); - dumpSet(set); - } - - // implement the ordering algorithm - enum OrderSeq { bottom_up, top_down }; - OrderSeq order; - std::vector R; - while (!set.empty()) { - std::vector pset = predSet(oNodes); - std::vector sset = succSet(oNodes); - - if (!pset.empty() && !vectorConj(pset, set).empty()) { - R = vectorConj(pset, set); - order = bottom_up; - } else if (!sset.empty() && !vectorConj(sset, set).empty()) { - R = vectorConj(sset, set); - order = top_down; - } else { - int maxASAP = -1; - int position = -1; - for (unsigned i = 0; i < set.size(); i++) { - int temp = set[i]->getASAP(); - if (temp > maxASAP) { - maxASAP = temp; - position = i; - } - } - R.push_back(set[position]); - order = bottom_up; - } - - while (!R.empty()) { - if (order == top_down) { - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "in top_down round\n"); - while (!R.empty()) { - int maxHeight = -1; - NodeVec::iterator chosenI; - for (NodeVec::iterator I = R.begin(); I != R.end(); I++) { - int temp = (*I)->height; - if ((temp > maxHeight) - || (temp == maxHeight && (*I)->mov <= (*chosenI)->mov)) { - - if ((temp > maxHeight) - || (temp == maxHeight && (*I)->mov < (*chosenI)->mov)) { - maxHeight = temp; - chosenI = I; - continue; - } - - //possible case: instruction A and B has the same height and mov, - //but A has dependence to B e.g B is the branch instruction in the - //end, or A is the phi instruction at the beginning - if ((*I)->mov == (*chosenI)->mov) - for (ModuloSchedGraphNode::const_iterator oe = - (*I)->beginOutEdges(), end = (*I)->endOutEdges(); - oe != end; oe++) { - if ((*oe)->getSink() == (*chosenI)) { - maxHeight = temp; - chosenI = I; - continue; - } - } - } - } - - ModuloSchedGraphNode *mu = *chosenI; - oNodes.push_back(mu); - R.erase(chosenI); - std::vector succ_mu = - succSet(mu, backEdgeSrc, backEdgeSink); - std::vector comm = - vectorConj(succ_mu, set); - comm = vectorSub(comm, oNodes); - R = vectorUnion(comm, R); - } - order = bottom_up; - R = vectorConj(predSet(oNodes), set); - } else { - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "in bottom up round\n"); - while (!R.empty()) { - int maxDepth = -1; - NodeVec::iterator chosenI; - for (NodeVec::iterator I = R.begin(); I != R.end(); I++) { - int temp = (*I)->depth; - if ((temp > maxDepth) - || (temp == maxDepth && (*I)->mov < (*chosenI)->mov)) { - maxDepth = temp; - chosenI = I; - } - } - ModuloSchedGraphNode *mu = *chosenI; - oNodes.push_back(mu); - R.erase(chosenI); - std::vector pred_mu = - predSet(mu, backEdgeSrc, backEdgeSink); - std::vector comm = - vectorConj(pred_mu, set); - comm = vectorSub(comm, oNodes); - R = vectorUnion(comm, R); - } - order = top_down; - R = vectorConj(succSet(oNodes), set); - } - } - if (ModuloScheduling::printScheduleProcess()) { - DEBUG_PRINT(std::cerr << "order finished\n"); - DEBUG_PRINT(std::cerr << "dumping the ordered nodes:\n"); - dumpSet(oNodes); - dumpCircuits(); - } - - //create a new set - //FIXME: the nodes between onodes and this circuit should also be include in - //this set - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "building the next set\n"); - set.clear(); - int k = -1; - setSeq++; - while (circuits[setSeq][++k] != 0) - set.push_back(getNode(circuits[setSeq][k])); - if (circuits[setSeq][0] != 0) { - backEdgeSrc = circuits[setSeq][k - 1]; - backEdgeSink = circuits[setSeq][0]; - } - - if (set.empty()) { - //no circuits any more - //collect all other nodes - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "no circuits any more, collect the rest nodes\n"); - for (unsigned i = 2; i < numNodes + 2; i++) { - bool inset = false; - for (unsigned j = 0; j < oNodes.size(); j++) - if (oNodes[j]->getNodeId() == i) { - inset = true; - break; - } - if (!inset) - set.push_back(getNode(i)); + //Ignore instructions of the void type + if(I->getType() != Type::VoidTy) { + + //Iterate over def-use chain and add true dependencies + for (Value::use_const_iterator U = I->use_begin(), e = I->use_end(); U != e; + ++U) { + if (Instruction *Inst = dyn_cast(*U)) { + //Check if a node already exists for this instruction + ModuloSchedGraph::iterator Sink = find(Inst); + + //If the instruction is in our graph, add appropriate edges + if(Sink->second != NULL) { + //assert if self loop + assert(&*I == Sink->first && "Use edge to itself!"); + + //Create edge and set delay equal to node latency + //FIXME: Is it safe to do this? + ModuloSchedGraph::iterator Src = find(I); + SchedGraphEdge *trueDep = new SchedGraphEdge(&*Src->second ,&*Sink->second, &*I, + SchedGraphEdge::TrueDep, + Src->second->getLatency()); + //Determine the iteration difference + //FIXME: Will this ever happen? + } + } } } - if (ModuloScheduling::printScheduleProcess()) { - DEBUG_PRINT(std::cerr << "next set is:\n"); - dumpSet(set); - } - } - -} - - - -/* - - build graph for instructions in this basic block - -*/ -void ModuloSchedGraph::buildGraph(const TargetMachine & target) -{ - - assert(this->bb && "The basicBlock is NULL?"); - - // Make a dummy root node. We'll add edges to the real roots later. - graphRoot = new ModuloSchedGraphNode(0, NULL, NULL, -1, target); - graphLeaf = new ModuloSchedGraphNode(1, NULL, NULL, -1, target); - - if (ModuloScheduling::printScheduleProcess()) - this->dump(bb); - - if (isLoop(bb)) { - - DEBUG_PRINT(cerr << "building nodes for this BasicBlock\n"); - buildNodesforBB(target, bb); - - DEBUG_PRINT(cerr << "adding def-use edge to this basic block\n"); - this->addDefUseEdges(bb); - - DEBUG_PRINT(cerr << "adding CD edges to this basic block\n"); - this->addCDEdges(bb); - - DEBUG_PRINT(cerr << "adding memory edges to this basicblock\n"); - this->addMemEdges(bb); - int ResII = this->computeResII(bb); - - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "ResII is " << ResII << "\n"); - - int RecII = this->computeRecII(bb); - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "RecII is " << RecII << "\n"); - - this->MII = std::max(ResII, RecII); - - this->computeNodeProperty(bb); - if (ModuloScheduling::printScheduleProcess()) - this->dumpNodeProperty(); - - this->orderNodes(); - - if (ModuloScheduling::printScheduleProcess()) - this->dump(); - } -} - -/* - get node with nodeId -*/ - -ModuloSchedGraphNode * -ModuloSchedGraph::getNode(const unsigned nodeId) const{ - for (const_iterator I = begin(), E = end(); I != E; I++) - if ((*I).second->getNodeId() == nodeId) - return (ModuloSchedGraphNode *) (*I).second; - return NULL; } -/* - compute RecurrenceII -*/ - -int -ModuloSchedGraph::computeRecII(const BasicBlock *bb){ - - int RecII = 0; - +void ModuloSchedGraph::ASAP() { - //FIXME: only deal with circuits starting at the first node: the phi node - //nodeId=2; - - //search all elementary circuits in the dependence graph - //assume maximum number of nodes is MAXNODE - - unsigned path[MAXNODE]; - unsigned stack[MAXNODE][MAXNODE]; - - for (int j = 0; j < MAXNODE; j++) { - path[j] = 0; - for (int k = 0; k < MAXNODE; k++) - stack[j][k] = 0; - } - - //in our graph, the node number starts at 2 - const unsigned numNodes = bb->size(); - - int i = 0; - path[i] = 2; - - ModuloSchedGraphNode *initNode = getNode(path[0]); - unsigned initNodeId = initNode->getNodeId(); - ModuloSchedGraphNode *currentNode = initNode; - - while (currentNode != NULL) { - unsigned currentNodeId = currentNode->getNodeId(); - // DEBUG_PRINT(std::cerr<<"current node is "<beginOutEdges(), E = currentNode->endOutEdges(); - I != E; I++) { - //DEBUG_PRINT(std::cerr <<" searching in outgoint edges of node - //"<getSink()->getNodeId(); - bool inpath = false, instack = false; - int k; - - //DEBUG_PRINT(std::cerr<<"nodeId is "< currentNodeId && !inpath && !instack) { - nextNode = - (ModuloSchedGraphNode *) ((SchedGraphEdge *) * I)->getSink(); - break; - } - } - - if (nextNode != NULL) { - //DEBUG_PRINT(std::cerr<<"find the next Node "<getNodeId()<<"\n"); - - int j = 0; - while (stack[i][j] != 0) - j++; - stack[i][j] = nextNode->getNodeId(); - - i++; - path[i] = nextNode->getNodeId(); - currentNode = nextNode; - } else { - //DEBUG_PRINT(std::cerr<<"no expansion any more"<<"\n"); - //confirmCircuit(); - for (ModuloSchedGraphNode::const_iterator I = - currentNode->beginOutEdges(), E = currentNode->endOutEdges(); - I != E; I++) { - unsigned nodeId = ((SchedGraphEdge *) * I)->getSink()->getNodeId(); - if (nodeId == initNodeId) { - - int j = -1; - while (circuits[++j][0] != 0); - for (int k = 0; k < MAXNODE; k++) - circuits[j][k] = path[k]; - - } - } - //remove this node in the path and clear the corresponding entries in the - //stack - path[i] = 0; - int j = 0; - for (j = 0; j < MAXNODE; j++) - stack[i][j] = 0; - i--; - currentNode = getNode(path[i]); - } - if (i == 0) { - - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "circuits found are:\n"); - int j = -1; - while (circuits[++j][0] != 0) { - int k = -1; - while (circuits[j][++k] != 0) - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << circuits[j][k] << "\t"); - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "\n"); - - //for this circuit, compute the sum of all edge delay - int sumDelay = 0; - k = -1; - while (circuits[j][++k] != 0) { - //ModuloSchedGraphNode* node =getNode(circuits[j][k]); - unsigned nextNodeId; - nextNodeId = - circuits[j][k + 1] != - 0 ? circuits[j][k + 1] : circuits[j][0]; - - sumDelay += - getMaxDelayEdge(circuits[j][k], nextNodeId)->getMinDelay(); - - } - // assume we have distance 1, in this case the sumDelay is RecII - // this is correct for SSA form only - // - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "The total Delay in the circuit is " << sumDelay - << "\n"); - - RecII = RecII > sumDelay ? RecII : sumDelay; - - } - return RecII; - } - - } - - return -1; -} - -/* - update resource usage vector (ruVec) -*/ -void -ModuloSchedGraph::addResourceUsage(std::vector > &ruVec, - int rid){ - - bool alreadyExists = false; - for (unsigned i = 0; i < ruVec.size(); i++) { - if (rid == ruVec[i].first) { - ruVec[i].second++; - alreadyExists = true; - break; - } - } - if (!alreadyExists) - ruVec.push_back(std::make_pair(rid, 1)); } -/* - dump the resource usage vector -*/ +void ModuloSchedGraph::ALAP() { -void -ModuloSchedGraph::dumpResourceUsage(std::vector > &ru){ - TargetSchedInfo & msi = (TargetSchedInfo &) target.getSchedInfo(); - - std::vector > resourceNumVector = msi.resourceNumVector; - DEBUG_PRINT(std::cerr << "resourceID\t" << "resourceNum\n"); - for (unsigned i = 0; i < resourceNumVector.size(); i++) - DEBUG_PRINT(std::cerr << resourceNumVector[i]. - first << "\t" << resourceNumVector[i].second << "\n"); - - DEBUG_PRINT(std::cerr << " maxNumIssueTotal(issue slot in one cycle) = " << msi. - maxNumIssueTotal << "\n"); - DEBUG_PRINT(std::cerr << "resourceID\t resourceUsage\t ResourceNum\n"); - for (unsigned i = 0; i < ru.size(); i++) { - DEBUG_PRINT(std::cerr << ru[i].first << "\t" << ru[i].second); - const unsigned resNum = msi.getCPUResourceNum(ru[i].first); - DEBUG_PRINT(std::cerr << "\t" << resNum << "\n"); - - } } -/* - compute thre resource restriction II -*/ +void ModuloSchedGraph::MOB() { -int -ModuloSchedGraph::computeResII(const BasicBlock * bb){ - - const TargetInstrInfo & mii = target.getInstrInfo(); - const TargetSchedInfo & msi = target.getSchedInfo(); - - int ResII; - std::vector > resourceUsage; - - for (BasicBlock::const_iterator I = bb->begin(), E = bb->end(); I != E; - I++) { - if (ModuloScheduling::printScheduleProcess()) { - DEBUG_PRINT(std::cerr << "machine instruction for llvm instruction( node " << - getGraphNodeForInst(I)->getNodeId() << ")\n"); - DEBUG_PRINT(std::cerr << "\t" << *I); - } - MachineCodeForInstruction & tempMvec = - MachineCodeForInstruction::get(I); - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "size =" << tempMvec.size() << "\n"); - for (unsigned i = 0; i < tempMvec.size(); i++) { - MachineInstr *minstr = tempMvec[i]; - - unsigned minDelay = mii.minLatency(minstr->getOpCode()); - InstrRUsage rUsage = msi.getInstrRUsage(minstr->getOpCode()); - InstrClassRUsage classRUsage = - msi.getClassRUsage(mii.getSchedClass(minstr->getOpCode())); - unsigned totCycles = classRUsage.totCycles; - - std::vector > resources=rUsage.resourcesByCycle; - assert(totCycles == resources.size()); - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "resources Usage for this Instr(totCycles=" - << totCycles << ",mindLatency=" - << mii.minLatency(minstr->getOpCode()) << "): " << *minstr - << "\n"); - for (unsigned j = 0; j < resources.size(); j++) { - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "cycle " << j << ": "); - for (unsigned k = 0; k < resources[j].size(); k++) { - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "\t" << resources[j][k]); - addResourceUsage(resourceUsage, resources[j][k]); - } - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "\n"); - } - } - } - if (ModuloScheduling::printScheduleProcess()) - this->dumpResourceUsage(resourceUsage); - - //compute ResII - ResII = 0; - int issueSlots = msi.maxNumIssueTotal; - for (unsigned i = 0; i < resourceUsage.size(); i++) { - int resourceNum = msi.getCPUResourceNum(resourceUsage[i].first); - int useNum = resourceUsage[i].second; - double tempII; - if (resourceNum <= issueSlots) - tempII = ceil(1.0 * useNum / resourceNum); - else - tempII = ceil(1.0 * useNum / issueSlots); - ResII = std::max((int) tempII, ResII); - } - return ResII; } +void ModuloSchedGraph::ComputeDepth() { - -/* - dump the basicblock -*/ - -void -ModuloSchedGraph::dump(const BasicBlock * bb){ - - DEBUG_PRINT(std::cerr << "dumping basic block:"); - DEBUG_PRINT(std::cerr << (bb->hasName()? bb->getName() : "block") - << " (" << bb << ")" << "\n"); - -} - -/* - dump the basicblock to ostream os -*/ - -void -ModuloSchedGraph::dump(const BasicBlock * bb, std::ostream & os){ - - os << "dumping basic block:"; - os << (bb->hasName()? bb->getName() : "block") - << " (" << bb << ")" << "\n"; } -/* - dump the graph -*/ - -void ModuloSchedGraph::dump() const -{ - DEBUG_PRINT(std::cerr << " ModuloSchedGraph for basic Blocks:"); - - DEBUG_PRINT(std::cerr << (bb->hasName()? bb->getName() : "block") - << " (" << bb << ")" << ""); - - DEBUG_PRINT(std::cerr << "\n\n Actual Root nodes : "); - for (unsigned i = 0, N = graphRoot->outEdges.size(); i < N; i++) - DEBUG_PRINT(std::cerr << graphRoot->outEdges[i]->getSink()->getNodeId() - << ((i == N - 1) ? "" : ", ")); - - DEBUG_PRINT(std::cerr << "\n Graph Nodes:\n"); - - unsigned numNodes = bb->size(); - for (unsigned i = 2; i < numNodes + 2; i++) { - ModuloSchedGraphNode *node = getNode(i); - DEBUG_PRINT(std::cerr << "\n" << *node); - } +void ModuloSchedGraph::ComputeHeight() { - DEBUG_PRINT(std::cerr << "\n"); } - -/* - dump all node property -*/ - -void ModuloSchedGraph::dumpNodeProperty() const -{ - - unsigned numNodes = bb->size(); - for (unsigned i = 2; i < numNodes + 2; i++) { - ModuloSchedGraphNode *node = getNode(i); - DEBUG_PRINT(std::cerr << "NodeId " << node->getNodeId() << "\t"); - DEBUG_PRINT(std::cerr << "ASAP " << node->getASAP() << "\t"); - DEBUG_PRINT(std::cerr << "ALAP " << node->getALAP() << "\t"); - DEBUG_PRINT(std::cerr << "mov " << node->getMov() << "\t"); - DEBUG_PRINT(std::cerr << "depth " << node->getDepth() << "\t"); - DEBUG_PRINT(std::cerr << "height " << node->getHeight() << "\t\n"); - } +void ModuloSchedGraphSet::addGraph(ModuloSchedGraph *graph) { + assert(graph!=NULL && "Graph for BasicBlock is null"); + Graphs.push_back(graph); } +ModuloSchedGraphSet::ModuloSchedGraphSet(const Function *F, + const TargetMachine &targ) + : function(F) { - -/************member functions for ModuloSchedGraphSet**************/ - -/* - constructor -*/ - -ModuloSchedGraphSet::ModuloSchedGraphSet(const Function *function, - const TargetMachine &target) -: method(function){ - - buildGraphsForMethod(method, target); - + //Create graph for each BB in this function + for (Function::const_iterator BI = F->begin(); BI != F->end(); ++BI) + addGraph(new ModuloSchedGraph(BI, targ)); } -/* - destructor -*/ - - ModuloSchedGraphSet::~ModuloSchedGraphSet(){ //delete all the graphs - for (iterator I = begin(), E = end(); I != E; ++I) - delete *I; } - - -/* - build graph for each basicblock in this method -*/ - -void -ModuloSchedGraphSet::buildGraphsForMethod(const Function *F, - const TargetMachine &target){ - - for (Function::const_iterator BI = F->begin(); BI != F->end(); ++BI){ - const BasicBlock* local_bb; - - local_bb=BI; - addGraph(new ModuloSchedGraph((BasicBlock*)local_bb, target)); - } - -} - -/* - dump the graph set -*/ - -void -ModuloSchedGraphSet::dump() const{ - - DEBUG_PRINT(std::cerr << " ====== ModuloSched graphs for function `" << - method->getName() << "' =========\n\n"); - for (const_iterator I = begin(); I != end(); ++I) - (*I)->dump(); - - DEBUG_PRINT(std::cerr << "\n=========End graphs for function `" << method->getName() - << "' ==========\n\n"); -} - - - - -/********************misc functions***************************/ - - -/* - dump the input basic block -*/ - -static void -dumpBasicBlock(const BasicBlock * bb){ - - DEBUG_PRINT(std::cerr << "dumping basic block:"); - DEBUG_PRINT(std::cerr << (bb->hasName()? bb->getName() : "block") - << " (" << bb << ")" << "\n"); -} - -/* - dump the input node -*/ - -std::ostream& operator<<(std::ostream &os, - const ModuloSchedGraphNode &node) -{ - os << std::string(8, ' ') - << "Node " << node.nodeId << " : " - << "latency = " << node.latency << "\n" << std::string(12, ' '); - - if (node.getInst() == NULL) - os << "(Dummy node)\n"; - else { - os << *node.getInst() << "\n" << std::string(12, ' '); - os << node.inEdges.size() << " Incoming Edges:\n"; - for (unsigned i = 0, N = node.inEdges.size(); i < N; i++) - os << std::string(16, ' ') << *node.inEdges[i]; - - os << std::string(12, ' ') << node.outEdges.size() - << " Outgoing Edges:\n"; - for (unsigned i = 0, N = node.outEdges.size(); i < N; i++) - os << std::string(16, ' ') << *node.outEdges[i]; - } - - return os; -} Index: llvm/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.h diff -u llvm/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.h:1.9 llvm/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.h:1.10 --- llvm/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.h:1.9 Sat Jul 26 18:01:04 2003 +++ llvm/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.h Thu Aug 28 12:12:14 2003 @@ -1,367 +1,101 @@ //===- ModuloSchedGraph.h - Modulo Scheduling Graph and Set -*- C++ -*-----===// -// -// This header defines the primative classes that make up a data structure -// graph. +// // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_MODULO_SCHED_GRAPH_H -#define LLVM_CODEGEN_MODULO_SCHED_GRAPH_H +#ifndef LLVM_MODULO_SCHED_GRAPH_H +#define LLVM_MODULO_SCHED_GRAPH_H #include "llvm/Instruction.h" +#include "llvm/CodeGen/SchedGraphCommon.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "Support/GraphTraits.h" +#include "llvm/BasicBlock.h" +#include "llvm/Function.h" #include "Support/hash_map" -#include "../InstrSched/SchedGraphCommon.h" -#include +#include -//===----------------------------------------------------------------------===// -// ModuloSchedGraphNode - Implement a data structure based on the -// SchedGraphNodeCommon this class stores informtion needed later to order the -// nodes in modulo scheduling -// -class ModuloSchedGraphNode:public SchedGraphNodeCommon { -private: - // the corresponding instruction - const Instruction *inst; - - // whether this node's property(ASAP,ALAP, ...) has been computed - bool propertyComputed; - - // ASAP: the earliest time the node could be scheduled - // ALAP: the latest time the node couldbe scheduled - // depth: the depth of the node - // height: the height of the node - // mov: the mobility function, computed as ALAP - ASAP - // scheTime: the scheduled time if this node has been scheduled - // earlyStart: the earliest time to be tried to schedule the node - // lateStart: the latest time to be tried to schedule the node - int ASAP, ALAP, depth, height, mov; - int schTime; - int earlyStart, lateStart; -public: +class ModuloSchedGraphNode : public SchedGraphNodeCommon { - //get the instruction - const Instruction *getInst() const { - return inst; - } - //get the instruction op-code name - const char *getInstOpcodeName() const { - return inst->getOpcodeName(); - } - //get the instruction op-code - const unsigned getInstOpcode() const { - return inst->getOpcode(); - } - - //return whether the node is NULL - bool isNullNode() const { - return (inst == NULL); - } - //return whether the property of the node has been computed - bool getPropertyComputed() { - return propertyComputed; - } - //set the propertyComputed - void setPropertyComputed(bool _propertyComputed) { - propertyComputed = _propertyComputed; - } - - //get the corresponding property - int getASAP() { - return ASAP; - } - int getALAP() { - return ALAP; - } - int getMov() { - return mov; - } - int getDepth() { - return depth; - } - int getHeight() { - return height; - } - int getSchTime() { - return schTime; - } - int getEarlyStart() { - return earlyStart; - } - int getLateStart() { - return lateStart; - } - void setEarlyStart(int _earlyStart) { - earlyStart = _earlyStart; - } - void setLateStart(int _lateStart) { - lateStart = _lateStart; - } - void setSchTime(int _time) { - schTime = _time; - } - -private: - friend class ModuloSchedGraph; - friend class SchedGraphNode; - - //constructor: - //nodeId: the node id, unique within the each BasicBlock - //_bb: which BasicBlock the corresponding instruction belongs to - //_inst: the corresponding instruction - //indexInBB: the corresponding instruction's index in the BasicBlock - //target: the targetMachine - ModuloSchedGraphNode(unsigned int _nodeId, - const BasicBlock * _bb, - const Instruction * _inst, - int indexInBB, const TargetMachine &target); - - - friend std::ostream & operator<<(std::ostream & os, - const ModuloSchedGraphNode & edge); - -}; - -//FIXME: these two value should not be used -#define MAXNODE 100 -#define MAXCC 100 - -//===----------------------------------------------------------------------===// -/// ModuloSchedGraph- the data structure to store dependence between nodes -/// it catches data dependence and constrol dependence -/// -class ModuloSchedGraph : - public SchedGraphCommon, - protected hash_map { - -private: - - BasicBlock* bb; - - //iteration Interval - int MII; - - //target machine - const TargetMachine & target; - - //the circuits in the dependence graph - unsigned circuits[MAXCC][MAXNODE]; - - //the order nodes - std::vector oNodes; - - typedef std::vector NodeVec; - - //the function to compute properties - void computeNodeASAP(const BasicBlock * in_bb); - void computeNodeALAP(const BasicBlock * in_bb); - void computeNodeMov(const BasicBlock * in_bb); - void computeNodeDepth(const BasicBlock * in_bb); - void computeNodeHeight(const BasicBlock * in_bb); - - //the function to compute node property - void computeNodeProperty(const BasicBlock * in_bb); - - //the function to sort nodes - void orderNodes(); - - //add the resource usage -void addResourceUsage(std::vector > &, int); - - //debug functions: - //dump circuits - void dumpCircuits(); - //dump the input set of nodes - void dumpSet(std::vector set); - //dump the input resource usage table - void dumpResourceUsage(std::vector > &); + const Instruction *Inst; //Node's Instruction + unsigned Earliest; //ASAP, or earliest time to be scheduled + unsigned Latest; //ALAP, or latested time to be scheduled + unsigned Depth; //Max Distance from node to the root + unsigned Height; //Max Distance from node to leaf + unsigned Mobility; //MOB, number of time slots it can be scheduled + const TargetMachine &Target; //Target information. public: - //help functions - - //get the maxium the delay between two nodes - SchedGraphEdge *getMaxDelayEdge(unsigned srcId, unsigned sinkId); - - //FIXME: - //get the predessor Set of the set - NodeVec predSet(NodeVec set, unsigned, unsigned); - NodeVec predSet(NodeVec set); - - //get the predessor set of the node - NodeVec predSet(ModuloSchedGraphNode *node, unsigned, unsigned); - NodeVec predSet(ModuloSchedGraphNode *node); - - //get the successor set of the set - NodeVec succSet(NodeVec set, unsigned, unsigned); - NodeVec succSet(NodeVec set); - - //get the succssor set of the node - NodeVec succSet(ModuloSchedGraphNode *node, unsigned, unsigned); - NodeVec succSet(ModuloSchedGraphNode *node); - - //return the uniton of the two vectors - NodeVec vectorUnion(NodeVec set1, NodeVec set2); + ModuloSchedGraphNode(unsigned ID, int index, const Instruction *inst, + const TargetMachine &target); - //return the consjuction of the two vectors - NodeVec vectorConj(NodeVec set1, NodeVec set2); - - //return all nodes in set1 but not set2 - NodeVec vectorSub(NodeVec set1, NodeVec set2); - - typedef hash_map map_base; - -public: - using map_base::iterator; - using map_base::const_iterator; - -public: - - //get target machine - const TargetMachine & getTarget() { - return target; - } - - //get the basic block - BasicBlock* getBasicBlock() const { - return bb; - } - - - //get the iteration interval - const int getMII() { - return MII; - } - - //get the ordered nodes - const NodeVec & getONodes() { - return oNodes; - } - - //get the number of nodes (including the root and leaf) - //note: actually root and leaf is not used - const unsigned int getNumNodes() const { - return size() + 2; - } - - //return wether the BasicBlock 'bb' contains a loop - bool isLoop(const BasicBlock *bb); - - //return the node for the input instruction - ModuloSchedGraphNode *getGraphNodeForInst(const Instruction *inst) const { - const_iterator onePair = this->find(inst); - return (onePair != this->end()) ? (*onePair).second : NULL; - } - - // Debugging support - //dump the graph - void dump() const; - - // dump the basicBlock - void dump(const BasicBlock *bb); - - //dump the basicBlock into 'os' stream - void dump(const BasicBlock *bb, std::ostream &os); - - //dump the node property - void dumpNodeProperty() const; + void print(std::ostream &os) const; + const Instruction* getInst() { return Inst; } + unsigned getEarliest() { return Earliest; } + unsigned getLatest() { return Latest; } + unsigned getDepth() { return Depth; } + unsigned getHeight() { return Height; } + unsigned getMobility() { return Mobility; } -private: - friend class ModuloSchedGraphSet; //give access to ctor - -public: - ModuloSchedGraph(BasicBlock * in_bb, - const TargetMachine & in_target) - :SchedGraphCommon(), bb(in_bb),target(in_target) - { - buildGraph(target); - } - - ~ModuloSchedGraph() { - for (const_iterator I = begin(); I != end(); ++I) - delete I->second; - } - - // Unorder iterators - // return values are pair - using map_base::begin; - using map_base::end; - - void addHash(const Instruction *inst, - ModuloSchedGraphNode *node){ - - assert((*this)[inst] == NULL); - (*this)[inst] = node; - - } - - // Graph builder - ModuloSchedGraphNode *getNode(const unsigned nodeId) const; - - // Build the graph from the basicBlock - void buildGraph(const TargetMachine &target); - - // Build nodes for BasicBlock - void buildNodesforBB(const TargetMachine &target, - const BasicBlock *bb); - - //find definitiona and use information for all nodes - void findDefUseInfoAtInstr(const TargetMachine &target, - ModuloSchedGraphNode *node, - NodeVec &memNode, - RegToRefVecMap ®ToRefVecMap, - ValueToDefVecMap &valueToDefVecMap); - - //add def-use edge - void addDefUseEdges(const BasicBlock *bb); - - //add control dependence edges - void addCDEdges(const BasicBlock *bb); + void setEarliest(unsigned early) { Earliest = early; } + void setLatest(unsigned late) { Latest = late; } + void setDepth(unsigned depth) { Depth = depth; } + void setHeight(unsigned height) { Height = height; } + void setMobility(unsigned mob) { Mobility = mob; } - //add memory dependence dges - void addMemEdges(const BasicBlock *bb); - //computer source restrictoin II - int computeResII(const BasicBlock *bb); - - //computer recurrence II - int computeRecII(const BasicBlock *bb); }; -//==================================- -// Graph set +class ModuloSchedGraph : public SchedGraphCommon { + + const BasicBlock *BB; //The Basic block this graph represents + const TargetMachine &Target; + hash_map GraphMap; + + void buildNodesForBB(); + +public: + typedef hash_map::iterator iterator; + typedef hash_map::const_iterator const_iterator; + + + ModuloSchedGraph(const BasicBlock *bb, const TargetMachine &targ); + + const BasicBlock* getBB() { return BB; } + void setBB(BasicBlock *bb) { BB = bb; } + unsigned size() { return GraphMap.size(); } + void addNode(const Instruction *I, ModuloSchedGraphNode *node); + void ASAP(); //Calculate earliest schedule time for all nodes in graph. + void ALAP(); //Calculate latest schedule time for all nodes in graph. + void MOB(); //Calculate mobility for all nodes in the graph. + void ComputeDepth(); //Compute depth of each node in graph + void ComputeHeight(); //Computer height of each node in graph + void addDepEdges(); //Add Dependencies + iterator find(const Instruction *I) { return GraphMap.find(I); } +}; -class ModuloSchedGraphSet : public std::vector { -private: - const Function *method; -public: - typedef std::vector baseVector; - using baseVector::iterator; - using baseVector::const_iterator; +class ModuloSchedGraphSet { + + const Function *function; //Function this set of graphs represent. + std::vector Graphs; public: - ModuloSchedGraphSet(const Function *function, const TargetMachine &target); + typedef std::vector::iterator iterator; + typedef std::vector::const_iterator const_iterator; + + iterator begin() { return Graphs.begin(); } + iterator end() { return Graphs.end(); } + + ModuloSchedGraphSet(const Function *func, const TargetMachine &target); ~ModuloSchedGraphSet(); - // Iterators - using baseVector::begin; - using baseVector::end; - - // Debugging support + void addGraph(ModuloSchedGraph *graph); void dump() const; -private: - void addGraph(ModuloSchedGraph *graph) { - assert(graph != NULL); - this->push_back(graph); - } - - // Graph builder - void buildGraphsForMethod(const Function *F, - const TargetMachine &target); + }; #endif Index: llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp diff -u llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.10 llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.11 --- llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.10 Wed Jul 23 09:59:40 2003 +++ llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp Thu Aug 28 12:12:14 2003 @@ -1,983 +1,35 @@ -//===- ModuloScheduling.cpp - Modulo Software Pipelining ------------------===// +//===-- ModuloScheduling.cpp - Software Pipeling Approach - SMS --*- C++ -*--=// // -// Implements the llvm/CodeGen/ModuloScheduling.h interface +// The is a software pipelining pass based on the Swing Modulo Scheduling +// alogrithm (SMS). // //===----------------------------------------------------------------------===// -#include "llvm/BasicBlock.h" -#include "llvm/Constants.h" -#include "llvm/iTerminators.h" -#include "llvm/iPHINode.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/MachineCodeForInstruction.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/InstrSelection.h" -#include "llvm/Target/TargetSchedInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "Support/CommandLine.h" -#include "Support/Statistic.h" #include "ModuloSchedGraph.h" -#include "ModuloScheduling.h" -#include -#include -//************************************************************ -// printing Debug information -// ModuloSchedDebugLevel stores the value of debug level -// modsched_os is the ostream to dump debug information, which is written into -// the file 'moduloSchedDebugInfo.output' -// see ModuloSchedulingPass::runOnFunction() -//************************************************************ +#include "llvm/Pass.h" +#include "llvm/Function.h" -ModuloSchedDebugLevel_t ModuloSchedDebugLevel; - -cl::opt -SDL_opt("modsched", cl::Hidden, cl::location(ModuloSchedDebugLevel), - cl::desc("enable modulo scheduling debugging information"), - cl::values(clEnumValN(ModuloSchedDebugLevel_NoDebugInfo, - "none", "disable debug output"), - clEnumValN(ModuloSchedDebugLevel_PrintSchedule, - "psched", "print original and new schedule"), - clEnumValN(ModuloSchedDebugLevel_PrintScheduleProcess, - "pschedproc", - "print how the new schdule is produced"), - 0)); - -// Computes the schedule and inserts epilogue and prologue -// -void -ModuloScheduling::instrScheduling(){ - - - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "************ computing modulo schedule ***********\n"); - - const TargetSchedInfo & msi = target.getSchedInfo(); - - //number of issue slots in the in each cycle - int numIssueSlots = msi.maxNumIssueTotal; - - //compute the schedule - bool success = false; - while (!success) { - //clear memory from the last round and initialize if necessary - clearInitMem(msi); - - //compute schedule and coreSchedule with the current II - success = computeSchedule(); - - if (!success) { - II++; - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "increase II to " << II << "\n"); - } - } - - //print the final schedule - dumpFinalSchedule(); - - //the schedule has been computed - //create epilogue, prologue and kernel BasicBlock - - //find the successor for this BasicBlock - BasicBlock *succ_bb = getSuccBB(bb); - - //print the original BasicBlock if necessary - if (ModuloScheduling::printSchedule()) { - DEBUG_PRINT(std::cerr << "dumping the orginal block\n"); - graph.dump(bb); - } - //construction of prologue, kernel and epilogue - - /* - BasicBlock *kernel = bb->splitBasicBlock(bb->begin()); - BasicBlock *prologue = bb; - BasicBlock *epilogue = kernel->splitBasicBlock(kernel->begin()); - */ - - // Construct prologue - /*constructPrologue(prologue);*/ - - // Construct kernel - - /*constructKernel(prologue, kernel, epilogue);*/ - - // Construct epilogue - - /*constructEpilogue(epilogue, succ_bb);*/ +namespace { - //print the BasicBlocks if necessary -// if (0){ -// DEBUG_PRINT(std::cerr << "dumping the prologue block:\n"); -// graph.dump(prologue); -// DEBUG_PRINT(std::cerr << "dumping the kernel block\n"); -// graph.dump(kernel); -// DEBUG_PRINT(std::cerr << "dumping the epilogue block\n"); -// graph.dump(epilogue); -// } - -} - - -// Clear memory from the last round and initialize if necessary -// - -void -ModuloScheduling::clearInitMem(const TargetSchedInfo & msi){ - - unsigned numIssueSlots = msi.maxNumIssueTotal; - // clear nodeScheduled from the last round - if (ModuloScheduling::printScheduleProcess()) { - DEBUG_PRINT(std::cerr << "***** new round with II= " << II << " ***********\n"); - DEBUG_PRINT(std::cerr << - " ************clear the vector nodeScheduled*************\n"); - } - nodeScheduled.clear(); - - // clear resourceTable from the last round and reset it - resourceTable.clear(); - for (unsigned i = 0; i < II; ++i) - resourceTable.push_back(msi.resourceNumVector); - - // clear the schdule and coreSchedule from the last round - schedule.clear(); - coreSchedule.clear(); - - // create a coreSchedule of size II*numIssueSlots - // each entry is NULL - while (coreSchedule.size() < II) { - std::vector < ModuloSchedGraphNode * >*newCycle = - new std::vector < ModuloSchedGraphNode * >(); - for (unsigned k = 0; k < numIssueSlots; ++k) - newCycle->push_back(NULL); - coreSchedule.push_back(*newCycle); - } -} - -// Compute schedule and coreSchedule with the current II -// -bool -ModuloScheduling::computeSchedule(){ - - - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "start to compute schedule\n"); - - // Loop over the ordered nodes - for (NodeVec::const_iterator I = oNodes.begin(); I != oNodes.end(); ++I) { - // Try to schedule for node I - if (ModuloScheduling::printScheduleProcess()) - dumpScheduling(); - ModuloSchedGraphNode *node = *I; - - // Compute whether this node has successor(s) - bool succ = true; - - // Compute whether this node has predessor(s) - bool pred = true; - - NodeVec schSucc = graph.vectorConj(nodeScheduled, graph.succSet(node)); - if (schSucc.empty()) - succ = false; - NodeVec schPred = graph.vectorConj(nodeScheduled, graph.predSet(node)); - if (schPred.empty()) - pred = false; - - //startTime: the earliest time we will try to schedule this node - //endTime: the latest time we will try to schedule this node - int startTime, endTime; - - //node's earlyStart: possible earliest time to schedule this node - //node's lateStart: possible latest time to schedule this node - node->setEarlyStart(-1); - node->setLateStart(9999); - - //this node has predessor but no successor - if (!succ && pred) { - // This node's earlyStart is it's predessor's schedule time + the edge - // delay - the iteration difference* II - for (unsigned i = 0; i < schPred.size(); i++) { - ModuloSchedGraphNode *predNode = schPred[i]; - SchedGraphEdge *edge = - graph.getMaxDelayEdge(predNode->getNodeId(), - node->getNodeId()); - int temp = - predNode->getSchTime() + edge->getMinDelay() - - edge->getIteDiff() * II; - node->setEarlyStart(std::max(node->getEarlyStart(), temp)); - } - startTime = node->getEarlyStart(); - endTime = node->getEarlyStart() + II - 1; - } - // This node has a successor but no predecessor - if (succ && !pred) { - for (unsigned i = 0; i < schSucc.size(); ++i) { - ModuloSchedGraphNode *succNode = schSucc[i]; - SchedGraphEdge *edge = - graph.getMaxDelayEdge(succNode->getNodeId(), - node->getNodeId()); - int temp = - succNode->getSchTime() - edge->getMinDelay() + - edge->getIteDiff() * II; - node->setLateStart(std::min(node->getEarlyStart(), temp)); - } - startTime = node->getLateStart() - II + 1; - endTime = node->getLateStart(); - } - // This node has both successors and predecessors - if (succ && pred) { - for (unsigned i = 0; i < schPred.size(); ++i) { - ModuloSchedGraphNode *predNode = schPred[i]; - SchedGraphEdge *edge = - graph.getMaxDelayEdge(predNode->getNodeId(), - node->getNodeId()); - int temp = - predNode->getSchTime() + edge->getMinDelay() - - edge->getIteDiff() * II; - node->setEarlyStart(std::max(node->getEarlyStart(), temp)); - } - for (unsigned i = 0; i < schSucc.size(); ++i) { - ModuloSchedGraphNode *succNode = schSucc[i]; - SchedGraphEdge *edge = - graph.getMaxDelayEdge(succNode->getNodeId(), - node->getNodeId()); - int temp = - succNode->getSchTime() - edge->getMinDelay() + - edge->getIteDiff() * II; - node->setLateStart(std::min(node->getEarlyStart(), temp)); - } - startTime = node->getEarlyStart(); - endTime = std::min(node->getLateStart(), - node->getEarlyStart() + ((int) II) - 1); - } - //this node has no successor or predessor - if (!succ && !pred) { - node->setEarlyStart(node->getASAP()); - startTime = node->getEarlyStart(); - endTime = node->getEarlyStart() + II - 1; - } - //try to schedule this node based on the startTime and endTime - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "scheduling the node " << (*I)->getNodeId() << "\n"); - - bool success = - this->ScheduleNode(node, startTime, endTime, nodeScheduled); - if (!success) - return false; - } - return true; -} - - -// Get the successor of the BasicBlock -// -BasicBlock * -ModuloScheduling::getSuccBB(BasicBlock *bb){ - - BasicBlock *succ_bb; - for (unsigned i = 0; i < II; ++i) - for (unsigned j = 0; j < coreSchedule[i].size(); ++j) - if (coreSchedule[i][j]) { - const Instruction *ist = coreSchedule[i][j]->getInst(); - - //we can get successor from the BranchInst instruction - //assume we only have one successor (besides itself) here - if (BranchInst::classof(ist)) { - BranchInst *bi = (BranchInst *) ist; - assert(bi->isConditional() && - "the branchInst is not a conditional one"); - assert(bi->getNumSuccessors() == 2 - && " more than two successors?"); - BasicBlock *bb1 = bi->getSuccessor(0); - BasicBlock *bb2 = bi->getSuccessor(1); - assert((bb1 == bb || bb2 == bb) && - " None of its successors is itself?"); - if (bb1 == bb) - succ_bb = bb2; - else - succ_bb = bb1; - return succ_bb; - } - } - assert(0 && "NO Successor?"); - return NULL; -} - - -// Get the predecessor of the BasicBlock -// -BasicBlock * -ModuloScheduling::getPredBB(BasicBlock *bb){ - - BasicBlock *pred_bb; - for (unsigned i = 0; i < II; ++i) - for (unsigned j = 0; j < coreSchedule[i].size(); ++j) - if (coreSchedule[i][j]) { - const Instruction *ist = coreSchedule[i][j]->getInst(); - - //we can get predecessor from the PHINode instruction - //assume we only have one predecessor (besides itself) here - if (PHINode::classof(ist)) { - PHINode *phi = (PHINode *) ist; - assert(phi->getNumIncomingValues() == 2 && - " the number of incoming value is not equal to two? "); - BasicBlock *bb1 = phi->getIncomingBlock(0); - BasicBlock *bb2 = phi->getIncomingBlock(1); - assert((bb1 == bb || bb2 == bb) && - " None of its predecessor is itself?"); - if (bb1 == bb) - pred_bb = bb2; - else - pred_bb = bb1; - return pred_bb; - } - } - assert(0 && " no predecessor?"); - return NULL; -} - - -// Construct the prologue -// -void -ModuloScheduling::constructPrologue(BasicBlock *prologue){ - - InstListType & prologue_ist = prologue->getInstList(); - vvNodeType & tempSchedule_prologue = - *(new std::vector >(schedule)); - - //compute the schedule for prologue - unsigned round = 0; - unsigned scheduleSize = schedule.size(); - while (round < scheduleSize / II) { - round++; - for (unsigned i = 0; i < scheduleSize; ++i) { - if (round * II + i >= scheduleSize) - break; - for (unsigned j = 0; j < schedule[i].size(); ++j) { - if (schedule[i][j]) { - assert(tempSchedule_prologue[round * II + i][j] == NULL && - "table not consitent with core table"); - // move the schedule one iteration ahead and overlap with the original - tempSchedule_prologue[round * II + i][j] = schedule[i][j]; - } - } - } - } - - // Clear the clone memory in the core schedule instructions - clearCloneMemory(); - - // Fill in the prologue - for (unsigned i = 0; i < ceil(1.0 * scheduleSize / II - 1) * II; ++i) - for (unsigned j = 0; j < tempSchedule_prologue[i].size(); ++j) - if (tempSchedule_prologue[i][j]) { - - //get the instruction - Instruction *orn = - (Instruction *) tempSchedule_prologue[i][j]->getInst(); - - //made a clone of it - Instruction *cln = cloneInstSetMemory(orn); - - //insert the instruction - prologue_ist.insert(prologue_ist.back(), cln); - - //if there is PHINode in the prologue, the incoming value from itself - //should be removed because it is not a loop any longer - if (PHINode::classof(cln)) { - PHINode *phi = (PHINode *) cln; - phi->removeIncomingValue(phi->getParent()); - } - } -} - - -// Construct the kernel BasicBlock -// -void -ModuloScheduling::constructKernel(BasicBlock *prologue, - BasicBlock *kernel, - BasicBlock *epilogue){ - - //*************fill instructions in the kernel**************** - InstListType & kernel_ist = kernel->getInstList(); - BranchInst *brchInst; - PHINode *phiInst, *phiCln; - - for (unsigned i = 0; i < coreSchedule.size(); ++i) - for (unsigned j = 0; j < coreSchedule[i].size(); ++j) - if (coreSchedule[i][j]) { - - // Take care of branch instruction differently with normal instructions - if (BranchInst::classof(coreSchedule[i][j]->getInst())) { - brchInst = (BranchInst *) coreSchedule[i][j]->getInst(); - continue; - } - // Take care of PHINode instruction differently with normal instructions - if (PHINode::classof(coreSchedule[i][j]->getInst())) { - phiInst = (PHINode *) coreSchedule[i][j]->getInst(); - Instruction *cln = cloneInstSetMemory(phiInst); - kernel_ist.insert(kernel_ist.back(), cln); - phiCln = (PHINode *) cln; - continue; - } - //for normal instructions: made a clone and insert it in the kernel_ist - Instruction *cln = - cloneInstSetMemory((Instruction *) coreSchedule[i][j]-> - getInst()); - kernel_ist.insert(kernel_ist.back(), cln); - } - // The two incoming BasicBlock for PHINode is the prologue and the kernel - // (itself) - phiCln->setIncomingBlock(0, prologue); - phiCln->setIncomingBlock(1, kernel); - - // The incoming value for the kernel (itself) is the new value which is - // computed in the kernel - Instruction *originalVal = (Instruction *) phiInst->getIncomingValue(1); - phiCln->setIncomingValue(1, originalVal->getClone()); - - // Make a clone of the branch instruction and insert it in the end - BranchInst *cln = (BranchInst *) cloneInstSetMemory(brchInst); - kernel_ist.insert(kernel_ist.back(), cln); - - // delete the unconditional branch instruction, which is generated when - // splitting the basicBlock - kernel_ist.erase(--kernel_ist.end()); - - // set the first successor to itself - cln->setSuccessor(0, kernel); - // set the second successor to eiplogue - cln->setSuccessor(1, epilogue); - - //*****change the condition******* - - //get the condition instruction - Instruction *cond = (Instruction *) cln->getCondition(); - - //get the condition's second operand, it should be a constant - Value *operand = cond->getOperand(1); - assert(ConstantSInt::classof(operand)); - - //change the constant in the condtion instruction - ConstantSInt *iteTimes = - ConstantSInt::get(operand->getType(), - ((ConstantSInt *) operand)->getValue() - II + 1); - cond->setOperand(1, iteTimes); - -} - - -// Construct the epilogue -// -void -ModuloScheduling::constructEpilogue(BasicBlock *epilogue, - BasicBlock *succ_bb){ - - //compute the schedule for epilogue - vvNodeType &tempSchedule_epilogue = - *(new std::vector >(schedule)); - unsigned scheduleSize = schedule.size(); - int round = 0; - while (round < ceil(1.0 * scheduleSize / II) - 1) { - round++; - for (unsigned i = 0; i < scheduleSize; i++) { - if (i + round * II >= scheduleSize) - break; - for (unsigned j = 0; j < schedule[i].size(); j++) - if (schedule[i + round * II][j]) { - assert(tempSchedule_epilogue[i][j] == NULL - && "table not consitant with core table"); - - //move the schdule one iteration behind and overlap - tempSchedule_epilogue[i][j] = schedule[i + round * II][j]; - } - } - } - - //fill in the epilogue - InstListType & epilogue_ist = epilogue->getInstList(); - for (unsigned i = II; i < scheduleSize; i++) - for (unsigned j = 0; j < tempSchedule_epilogue[i].size(); j++) - if (tempSchedule_epilogue[i][j]) { - Instruction *inst = - (Instruction *) tempSchedule_epilogue[i][j]->getInst(); - - //BranchInst and PHINode should be treated differently - //BranchInst:unecessary, simly omitted - //PHINode: omitted - if (!BranchInst::classof(inst) && !PHINode::classof(inst)) { - //make a clone instruction and insert it into the epilogue - Instruction *cln = cloneInstSetMemory(inst); - epilogue_ist.push_front(cln); - } - } - - //*************delete the original instructions****************// - //to delete the original instructions, we have to make sure their use is zero - - //update original core instruction's uses, using its clone instread - for (unsigned i = 0; i < II; i++) - for (unsigned j = 0; j < coreSchedule[i].size(); j++) { - if (coreSchedule[i][j]) - updateUseWithClone((Instruction *) coreSchedule[i][j]->getInst()); - } - - //erase these instructions - for (unsigned i = 0; i < II; i++) - for (unsigned j = 0; j < coreSchedule[i].size(); j++) - if (coreSchedule[i][j]) { - Instruction *ist = (Instruction *) coreSchedule[i][j]->getInst(); - ist->getParent()->getInstList().erase(ist); - } - - - - //finally, insert an unconditional branch instruction at the end - epilogue_ist.push_back(new BranchInst(succ_bb)); - -} - - -//------------------------------------------------------------------------------ -//this function replace the value(instruction) ist in other instructions with -//its latest clone i.e. after this function is called, the ist is not used -//anywhere and it can be erased. -//------------------------------------------------------------------------------ -void -ModuloScheduling::updateUseWithClone(Instruction * ist){ - - - while (ist->use_size() > 0) { - bool destroyed = false; - - //other instruction is using this value ist - assert(Instruction::classof(*ist->use_begin())); - Instruction *inst = (Instruction *) (*ist->use_begin()); - - for (unsigned i = 0; i < inst->getNumOperands(); i++) - if (inst->getOperand(i) == ist && ist->getClone()) { - // if the instruction is TmpInstruction, simly delete it because it has - // no parent and it does not belongs to any BasicBlock - if (TmpInstruction::classof(inst)) { - delete inst; - destroyed = true; - break; - } - - //otherwise, set the instruction's operand to the value's clone - inst->setOperand(i, ist->getClone()); - - //the use from the original value ist is destroyed - destroyed = true; - break; - } - if (!destroyed) { - //if the use can not be destroyed , something is wrong - inst->dump(); - assert(0 && "this use can not be destroyed"); - } - } - -} - - -//******************************************************** -//this function clear all clone mememoy -//i.e. set all instruction's clone memory to NULL -//***************************************************** -void -ModuloScheduling::clearCloneMemory(){ - - for (unsigned i = 0; i < coreSchedule.size(); i++) - for (unsigned j = 0; j < coreSchedule[i].size(); j++) - if (coreSchedule[i][j]) - ((Instruction *) coreSchedule[i][j]->getInst())->clearClone(); - -} - - -//****************************************************************************** -// this function make a clone of the instruction orn the cloned instruction will -// use the orn's operands' latest clone as its operands it is done this way -// because LLVM is in SSA form and we should use the correct value -//this fuction also update the instruction orn's latest clone memory -//****************************************************************************** -Instruction * -ModuloScheduling::cloneInstSetMemory(Instruction * orn){ - - // make a clone instruction - Instruction *cln = orn->clone(); - - // update the operands - for (unsigned k = 0; k < orn->getNumOperands(); k++) { - const Value *op = orn->getOperand(k); - if (Instruction::classof(op) && ((Instruction *) op)->getClone()) { - Instruction *op_inst = (Instruction *) op; - cln->setOperand(k, op_inst->getClone()); - } - } - - // update clone memory - orn->setClone(cln); - return cln; -} - - - -bool -ModuloScheduling::ScheduleNode(ModuloSchedGraphNode * node, - unsigned start, unsigned end, - NodeVec & nodeScheduled){ - - const TargetSchedInfo & msi = target.getSchedInfo(); - unsigned int numIssueSlots = msi.maxNumIssueTotal; - - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "startTime= " << start << " endTime= " << end << "\n"); - bool isScheduled = false; - for (unsigned i = start; i <= end; i++) { - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << " now try cycle " << i << ":" << "\n"); - for (unsigned j = 0; j < numIssueSlots; j++) { - unsigned int core_i = i % II; - unsigned int core_j = j; - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << "\t Trying slot " << j << "..........."); - //check the resouce table, make sure there is no resource conflicts - const Instruction *instr = node->getInst(); - MachineCodeForInstruction & tempMvec = - MachineCodeForInstruction::get(instr); - bool resourceConflict = false; - const TargetInstrInfo & mii = msi.getInstrInfo(); - - if (coreSchedule.size() < core_i + 1 - || !coreSchedule[core_i][core_j]) { - //this->dumpResourceUsageTable(); - int latency = 0; - for (unsigned k = 0; k < tempMvec.size(); k++) { - MachineInstr *minstr = tempMvec[k]; - InstrRUsage rUsage = msi.getInstrRUsage(minstr->getOpCode()); - std::vector < std::vector < resourceId_t > >resources - = rUsage.resourcesByCycle; - updateResourceTable(resources, i + latency); - latency += std::max(mii.minLatency(minstr->getOpCode()), 1); - } - - //this->dumpResourceUsageTable(); - - latency = 0; - if (resourceTableNegative()) { - - //undo-update the resource table - for (unsigned k = 0; k < tempMvec.size(); k++) { - MachineInstr *minstr = tempMvec[k]; - InstrRUsage rUsage = msi.getInstrRUsage(minstr->getOpCode()); - std::vector < std::vector < resourceId_t > >resources - = rUsage.resourcesByCycle; - undoUpdateResourceTable(resources, i + latency); - latency += std::max(mii.minLatency(minstr->getOpCode()), 1); - } - resourceConflict = true; - } - } - if (!resourceConflict && !coreSchedule[core_i][core_j]) { - if (ModuloScheduling::printScheduleProcess()) { - DEBUG_PRINT(std::cerr << " OK!" << "\n"); - DEBUG_PRINT(std::cerr << "Node " << node->getNodeId() << " scheduled.\n"); - } - //schedule[i][j]=node; - while (schedule.size() <= i) { - std::vector < ModuloSchedGraphNode * >*newCycle = - new std::vector < ModuloSchedGraphNode * >(); - for (unsigned k = 0; k < numIssueSlots; k++) - newCycle->push_back(NULL); - schedule.push_back(*newCycle); - } - std::vector::iterator startIterator; - startIterator = schedule[i].begin(); - schedule[i].insert(startIterator + j, node); - startIterator = schedule[i].begin(); - schedule[i].erase(startIterator + j + 1); - - //update coreSchedule - //coreSchedule[core_i][core_j]=node; - while (coreSchedule.size() <= core_i) { - std::vector *newCycle = - new std::vector(); - for (unsigned k = 0; k < numIssueSlots; k++) - newCycle->push_back(NULL); - coreSchedule.push_back(*newCycle); - } - - startIterator = coreSchedule[core_i].begin(); - coreSchedule[core_i].insert(startIterator + core_j, node); - startIterator = coreSchedule[core_i].begin(); - coreSchedule[core_i].erase(startIterator + core_j + 1); - - node->setSchTime(i); - isScheduled = true; - nodeScheduled.push_back(node); - - break; - } else if (coreSchedule[core_i][core_j]) { - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << " Slot not available\n"); - } else { - if (ModuloScheduling::printScheduleProcess()) - DEBUG_PRINT(std::cerr << " Resource conflicts\n"); - } - } - if (isScheduled) - break; - } - //assert(nodeScheduled &&"this node can not be scheduled?"); - return isScheduled; -} - - -void -ModuloScheduling::updateResourceTable(Resources useResources, - int startCycle){ - - for (unsigned i = 0; i < useResources.size(); i++) { - int absCycle = startCycle + i; - int coreCycle = absCycle % II; - std::vector > &resourceRemained = - resourceTable[coreCycle]; - std::vector < unsigned int >&resourceUsed = useResources[i]; - for (unsigned j = 0; j < resourceUsed.size(); j++) { - for (unsigned k = 0; k < resourceRemained.size(); k++) - if ((int) resourceUsed[j] == resourceRemained[k].first) { - resourceRemained[k].second--; - } - } - } -} - -void -ModuloScheduling::undoUpdateResourceTable(Resources useResources, - int startCycle){ - - for (unsigned i = 0; i < useResources.size(); i++) { - int absCycle = startCycle + i; - int coreCycle = absCycle % II; - std::vector > &resourceRemained = - resourceTable[coreCycle]; - std::vector < unsigned int >&resourceUsed = useResources[i]; - for (unsigned j = 0; j < resourceUsed.size(); j++) { - for (unsigned k = 0; k < resourceRemained.size(); k++) - if ((int) resourceUsed[j] == resourceRemained[k].first) { - resourceRemained[k].second++; - } - } - } -} - - -//----------------------------------------------------------------------- -// Function: resourceTableNegative -// return value: -// return false if any element in the resouceTable is negative -// otherwise return true -// Purpose: - -// this function is used to determine if an instruction is eligible for -// schedule at certain cycle -//----------------------------------------------------------------------- - - -bool -ModuloScheduling::resourceTableNegative(){ - - assert(resourceTable.size() == (unsigned) II - && "resouceTable size must be equal to II"); - bool isNegative = false; - for (unsigned i = 0; i < resourceTable.size(); i++) - for (unsigned j = 0; j < resourceTable[i].size(); j++) { - if (resourceTable[i][j].second < 0) { - isNegative = true; - break; - } - } - return isNegative; -} - - -//---------------------------------------------------------------------- -// Function: dumpResouceUsageTable -// Purpose: -// print out ResouceTable for debug -// -//------------------------------------------------------------------------ - -void -ModuloScheduling::dumpResourceUsageTable(){ - - DEBUG_PRINT(std::cerr << "dumping resource usage table\n"); - for (unsigned i = 0; i < resourceTable.size(); i++) { - for (unsigned j = 0; j < resourceTable[i].size(); j++) - DEBUG_PRINT(std::cerr << resourceTable[i][j].first - << ":" << resourceTable[i][j].second << " "); - DEBUG_PRINT(std::cerr << "\n"); - } - -} - -//---------------------------------------------------------------------- -//Function: dumpSchedule -//Purpose: -// print out thisSchedule for debug -// -//----------------------------------------------------------------------- -void -ModuloScheduling::dumpSchedule(vvNodeType thisSchedule){ - - const TargetSchedInfo & msi = target.getSchedInfo(); - unsigned numIssueSlots = msi.maxNumIssueTotal; - for (unsigned i = 0; i < numIssueSlots; i++) - DEBUG_PRINT(std::cerr << "\t#"); - DEBUG_PRINT(std::cerr << "\n"); - for (unsigned i = 0; i < thisSchedule.size(); i++) { - DEBUG_PRINT(std::cerr << "cycle" << i << ": "); - for (unsigned j = 0; j < thisSchedule[i].size(); j++) - if (thisSchedule[i][j] != NULL) - DEBUG_PRINT(std::cerr << thisSchedule[i][j]->getNodeId() << "\t"); - else - DEBUG_PRINT(std::cerr << "\t"); - DEBUG_PRINT(std::cerr << "\n"); - } -} - - -//---------------------------------------------------- -//Function: dumpScheduling -//Purpose: -// print out the schedule and coreSchedule for debug -// -//------------------------------------------------------- - -void -ModuloScheduling::dumpScheduling(){ - - DEBUG_PRINT(std::cerr << "dump schedule:" << "\n"); - const TargetSchedInfo & msi = target.getSchedInfo(); - unsigned numIssueSlots = msi.maxNumIssueTotal; - for (unsigned i = 0; i < numIssueSlots; i++) - DEBUG_PRINT(std::cerr << "\t#"); - DEBUG_PRINT(std::cerr << "\n"); - for (unsigned i = 0; i < schedule.size(); i++) { - DEBUG_PRINT(std::cerr << "cycle" << i << ": "); - for (unsigned j = 0; j < schedule[i].size(); j++) - if (schedule[i][j] != NULL) - DEBUG_PRINT(std::cerr << schedule[i][j]->getNodeId() << "\t"); - else - DEBUG_PRINT(std::cerr << "\t"); - DEBUG_PRINT(std::cerr << "\n"); - } - - DEBUG_PRINT(std::cerr << "dump coreSchedule:" << "\n"); - for (unsigned i = 0; i < numIssueSlots; i++) - DEBUG_PRINT(std::cerr << "\t#"); - DEBUG_PRINT(std::cerr << "\n"); - for (unsigned i = 0; i < coreSchedule.size(); i++) { - DEBUG_PRINT(std::cerr << "cycle" << i << ": "); - for (unsigned j = 0; j < coreSchedule[i].size(); j++) - if (coreSchedule[i][j] != NULL) - DEBUG_PRINT(std::cerr << coreSchedule[i][j]->getNodeId() << "\t"); - else - DEBUG_PRINT(std::cerr << "\t"); - DEBUG_PRINT(std::cerr << "\n"); - } -} - -/* - print out final schedule -*/ - -void -ModuloScheduling::dumpFinalSchedule(){ - - std::cerr << "dump schedule:" << "\n"; - const TargetSchedInfo & msi = target.getSchedInfo(); - unsigned numIssueSlots = msi.maxNumIssueTotal; - - for (unsigned i = 0; i < numIssueSlots; i++) - std::cerr << "\t#"; - std::cerr << "\n"; - - for (unsigned i = 0; i < schedule.size(); i++) { - std::cerr << "cycle" << i << ": "; + class ModuloScheduling : public FunctionPass { - for (unsigned j = 0; j < schedule[i].size(); j++) - if (schedule[i][j] != NULL) - std::cerr << schedule[i][j]->getNodeId() << "\t"; - else - std::cerr << "\t"; - std::cerr << "\n"; - } - - std::cerr << "dump coreSchedule:" << "\n"; - for (unsigned i = 0; i < numIssueSlots; i++) - std::cerr << "\t#"; - std::cerr << "\n"; - - for (unsigned i = 0; i < coreSchedule.size(); i++) { - std::cerr << "cycle" << i << ": "; - for (unsigned j = 0; j < coreSchedule[i].size(); j++) - if (coreSchedule[i][j] != NULL) - std::cerr << coreSchedule[i][j]->getNodeId() << "\t"; - else - std::cerr << "\t"; - std::cerr << "\n"; - } -} - -//--------------------------------------------------------------------------- -// Function: ModuloSchedulingPass -// -// Purpose: -// Entry point for Modulo Scheduling -// Schedules LLVM instruction -// -//--------------------------------------------------------------------------- - -namespace { - class ModuloSchedulingPass:public FunctionPass { - const TargetMachine ⌖ - public: - ModuloSchedulingPass(const TargetMachine &T):target(T) {} - - const char *getPassName() const { - return "Modulo Scheduling"; - } - - // getAnalysisUsage - We use LiveVarInfo... - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - //AU.addRequired(FunctionLiveVarInfo::ID); - } - - bool runOnFunction(Function & F); + virtual bool runOnFunction(Function &F); }; -} // end anonymous namespace + RegisterOpt X("modulo-sched", "Modulo Scheduling/Software Pipelining"); +} -bool -ModuloSchedulingPass::runOnFunction(Function &F){ - - ModuloSchedGraphSet *graphSet = new ModuloSchedGraphSet(&F, target); - - ModuloSchedulingSet ModuloSchedulingSet(*graphSet); - - DEBUG_PRINT(std::cerr<<"runOnFunction in ModuloSchedulingPass returns\n"<<"\n"); - return false; +//Create Modulo Scheduling Pass +Pass *createModuloSchedPass() { + return new ModuloScheduling(); } +//ModuloScheduling::runOnFunction - Main transformation entry point. +bool ModuloScheduling::runOnFunction(Function &F) { + bool Changed = false; -Pass * -createModuloSchedulingPass(const TargetMachine & tgt){ - DEBUG_PRINT(std::cerr<<"creating modulo scheduling\n"); - return new ModuloSchedulingPass(tgt); + return Changed; } + From tbrethou at cs.uiuc.edu Thu Aug 28 12:19:02 2003 From: tbrethou at cs.uiuc.edu (Tanya Brethour) Date: Thu Aug 28 12:19:02 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.cpp README Message-ID: <200308281718.MAA24651@tank.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/ModuloScheduling: ModuloSchedGraph.cpp updated: 1.11 -> 1.12 README (r1.2) removed --- Log message: Removing README --- Diffs of the changes: Index: llvm/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.cpp diff -u llvm/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.cpp:1.11 llvm/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.cpp:1.12 --- llvm/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.cpp:1.11 Thu Aug 28 12:12:14 2003 +++ llvm/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.cpp Thu Aug 28 12:17:59 2003 @@ -71,8 +71,8 @@ //Create edge and set delay equal to node latency //FIXME: Is it safe to do this? ModuloSchedGraph::iterator Src = find(I); - SchedGraphEdge *trueDep = new SchedGraphEdge(&*Src->second ,&*Sink->second, &*I, - SchedGraphEdge::TrueDep, + SchedGraphEdge *trueDep = new SchedGraphEdge(&*Src->second ,&*Sink->second, + &*I, SchedGraphEdge::TrueDep, Src->second->getLatency()); //Determine the iteration difference //FIXME: Will this ever happen? From gaeke at cs.uiuc.edu Thu Aug 28 12:40:03 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Aug 28 12:40:03 2003 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/TraceToFunction.cpp Message-ID: <200308281739.MAA20298@trinity.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: TraceToFunction.cpp added (r1.1) --- Log message: Initial checkin of TraceToFunction converter. --- Diffs of the changes: Index: reopt/lib/LightWtProfiling/TraceToFunction.cpp diff -c /dev/null reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.1 *** /dev/null Thu Aug 28 12:39:14 2003 --- reopt/lib/LightWtProfiling/TraceToFunction.cpp Thu Aug 28 12:39:03 2003 *************** *** 0 **** --- 1,484 ---- + //===- TraceToFunction.cpp - Convert traces to functions ---------*- C++ -*--=// + // + // Repackage traces as functions. + // + //===----------------------------------------------------------------------===// + + #include "Trace.h" + #include "llvm/Transforms/Utils/Cloning.h" + #include "llvm/Pass.h" + #include "llvm/Module.h" + #include "llvm/DerivedTypes.h" + #include "llvm/iTerminators.h" + #include "llvm/iPHINode.h" + #include "llvm/iMemory.h" + #include "llvm/iOther.h" + #include "llvm/Constants.h" + #include "Support/StringExtras.h" // for utostr() + #include "Support/Debug.h" // for DEBUG() + #include + + typedef std::vector TypeVector; + typedef std::set LiveVariableSet; + typedef std::map ValueToIntMap; + typedef std::map ValueMap; + typedef std::map BranchNumberMap; + + class TraceToFunction { + ValueToIntMap LiveInToParameterMap; + BranchNumberMap BranchNumber; + virtual TypeVector createFunctionArgTypeVector (PointerType *ST, + LiveVariableSet S); + virtual void fillInFunctionBody (Trace &T, Function *F, LiveVariableSet &So); + virtual void fixupFunctionBodyBB (Trace &T, Function *F, BasicBlock *srcB, + BasicBlock *dstB, ValueMap &O2CMap, + LiveVariableSet &So); + public: + TraceToFunction () { } + virtual ~TraceToFunction () { } + virtual Function *traceToFunction (Trace &T); + }; + + /// getTraceLiveInSet - Return the set of variables which are used in + /// the trace but which are not defined in the trace. + /// + static LiveVariableSet getTraceLiveInSet (Trace &T) { + LiveVariableSet S; + for (Trace::iterator TI = T.begin (), TE = T.end (); TI != TE; ++TI) { + BasicBlock *B = *TI; + // B is a basic block in the trace. + for (BasicBlock::iterator BI = B->begin (), BE = B->end (); BI != BE; ++BI){ + Instruction &I = *BI; + // I is an instruction in B, which is in the trace. + for (unsigned i = 0; i < I.getNumOperands (); ++i) { + Value *V = I.getOperand (i); + // V is used in the trace by instruction I. + if (Instruction *VI = dyn_cast (V)) + // V is defined by an instruction; not a constant or global. + if (!T.contains (VI->getParent ())) + // V is defined by an instruction outside the trace. + S.insert (V); + } + } + } + return S; + } + + /// getTraceLiveOutSet - Return the set of variables which are defined + /// by an instruction inside the trace, and used in an instruction + /// outside the trace (but within that trace's function.) + /// + static LiveVariableSet getTraceLiveOutSet (Trace &T) { + LiveVariableSet S; + Function &F = *T.getFunction(); + for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) { + BasicBlock &B = *FI; + if (!T.contains (&B)) { + for (BasicBlock::iterator BI = B.begin(), BE = B.end(); BI != BE; ++BI) { + Instruction &I = *BI; + // I is an instruction in the trace's function, but outside the trace. + // Check its operands for uses of values defined in the trace. + for (unsigned i = 0; i < I.getNumOperands (); ++i) { + Value *V = I.getOperand (i); + // V is used outside the trace by instruction I. + if (Instruction *VI = dyn_cast (V)) + // V is defined by an instruction; not a constant or global. + if (T.contains (VI->getParent ())) + // V is defined by an instruction inside the trace. + S.insert (V); + } + } + } + } + return S; + } + + /// containsTraceExitingBranch - If B contains a branch instruction BI + /// that exits the trace T, returns BI. Returns NULL otherwise. + /// + static BranchInst *containsTraceExitingBranch (BasicBlock *B, Trace T) { + TerminatorInst *TI = B->getTerminator (); + assert (TI && "Only works on well-formed LLVM basic blocks w/ terminators"); + if (BranchInst *BI = dyn_cast (TI)) + for (unsigned i = 0; i < BI->getNumSuccessors (); ++i) { + BasicBlock *BIT = BI->getSuccessor (i); + if (!T.contains (BIT)) + return BI; + } + return NULL; + } + + /// createLiveOutType - Given the live-out set S of a trace, create a + /// pointer-to-structure type that will encapsulate all the live-outs from S. + /// + static PointerType *createLiveOutType (LiveVariableSet S) { + TypeVector T; + // For each variable in S, make a new entry in T having its type. + for (LiveVariableSet::iterator I = S.begin (), E = S.end (); I != E; ++I) { + T.push_back ((*I)->getType ()); + } + return PointerType::get (StructType::get (T)); + } + + /// createFunctionArgTypeVector - Given the live-in set S of a trace, + /// create a parameter list containing a parameter for each of the + /// variables in S as well as a pointer-to-structure type PST to fill + /// in which contains the live-outs. As a side effect, fill in the + /// mapping between live-ins and parameters in the global map named + /// LiveInToParameterMap. + /// + TypeVector TraceToFunction::createFunctionArgTypeVector (PointerType *PST, + LiveVariableSet S) { + TypeVector P; + P.push_back (PST); + + LiveInToParameterMap.clear (); + for (LiveVariableSet::iterator I = S.begin (), E = S.end (); I != E; ++I) { + Value *V = *I; + P.push_back (V->getType ()); + LiveInToParameterMap[V] = P.size () - 1; + } + // Print out mapping of instructions to arg numbers. + DEBUG(for (ValueToIntMap::iterator I = LiveInToParameterMap.begin (), + E = LiveInToParameterMap.end (); I != E; ++I) + std::cerr << I->first << " is parameter " << I->second << "\n"); + return P; + } + + /// giveNamesToFunctionArgs - Name the first argument of F "liveOut", + /// then use the ordering imposed by S's iterator to name the + /// remaining arguments of F. + /// + static void giveNamesToFunctionArgs (LiveVariableSet S, Function *F) { + Function::aiterator argIterator = F->abegin (); + unsigned argPosition = 0; + + argIterator->setName ("liveOut"); // Arg 0 is always the live-out struct. + ++argPosition; + ++argIterator; + + for (LiveVariableSet::iterator I = S.begin (), E = S.end (); I != E; ++I) { + std::string name ((*I)->getName ()); + if (name == "") + name = "arg" + utostr (argPosition); + argIterator->setName ("liveIn." + name); + ++argPosition; + ++argIterator; + } + } + + /// numberExitBranchesInTrace - Fill in M with pairs that map each + /// trace-exiting branch in T to a unique nonnegative integer. + /// + static void numberExitBranchesInTrace (Trace &T, BranchNumberMap &M) { + int Count = M.size (); + for (Trace::iterator I = T.begin (), E = T.end (); I != E; ++I) { + BasicBlock *B = *I; + BranchInst *BI = containsTraceExitingBranch (B, T); + if (BI) + M[BI] = Count++; + } + } + + /// getFunctionArg - Return a pointer to F's ARGNOth argument. + /// + static Argument *getFunctionArg (Function *F, unsigned argno) { + Function::aiterator ai = F->abegin (); + while (argno) { ++ai; --argno; } + return &*ai; + } + + /// cloneTraceBBsIntoFunction - Copy the BasicBlocks of the trace T into + /// the new Function F, which should be initially empty. Correspondences + /// between Original instructions (in T) and their Clones (in F) are added + /// to O2CMap. + /// + static void cloneTraceBBsIntoFunction (Trace &T, Function *F, ValueMap &O2CMap){ + unsigned BBCount = 0; + // Clone each basic block into the new function. + for (Trace::iterator TI = T.begin (), TE = T.end (); TI != TE; ++TI) { + BasicBlock *srcB = *TI; + // Create a new BasicBlock dstB that corresponds to srcB in T. + BasicBlock *dstB = CloneBasicBlock (srcB, O2CMap, ".ttf"); + DEBUG(dstB->setName ("trace" + utostr(BBCount++))); + // Add dstB to F. + F->getBasicBlockList ().push_back (dstB); + // Remember the correspondence between srcB and dstB. + // FIXME: Should this be something that CloneBasicBlock does? + O2CMap[srcB] = dstB; + } + } + + /// fillInFunctionBody - Clone the BBs of T into F, then do all + /// necessary fixups to ensure that F's new contents are internally + /// consistent and that the live-outs So get stored in F's first + /// argument. + /// + void TraceToFunction::fillInFunctionBody (Trace &T, Function *F, + LiveVariableSet &So) { + ValueMap O2CMap; + // First copy the basic blocks from the trace. + cloneTraceBBsIntoFunction (T, F, O2CMap); + + numberExitBranchesInTrace (T, BranchNumber); + + // Fix up the cloned basic blocks of the function so that they are + // internally consistent. + for (Trace::iterator TI = T.begin (), TE = T.end (); TI != TE; ++TI) { + BasicBlock *srcB = *TI; + assert (O2CMap[srcB] && "Can't find clone of basic block I just cloned"); + BasicBlock *dstB = dyn_cast (O2CMap[srcB]); + assert (dstB && "Clone of basic block I just cloned is not a basic block"); + fixupFunctionBodyBB (T, F, srcB, dstB, O2CMap, So); + } + } + + /// fixupFunctionBodyBB - Given srcB in T and its clone dstB in F, and + /// the map O2CMap detailing the correspondences between values in T + /// and values in F, fix up dstB so that its contents are internally + /// consistent, and so that it stores its live-out values So in F's first + /// argument. (This is where all the magic gets done...) + /// + void TraceToFunction::fixupFunctionBodyBB (Trace &T, Function *F, + BasicBlock *srcB, BasicBlock *dstB, + ValueMap &O2CMap, + LiveVariableSet &So) { + // Additional special handling for trace's entry basic block: + // The old entry BB's clone will start with a phi, one of whose args + // comes from off-trace (that's the trace entry point.) We can't + // leave that there because the off-trace source BB is now out of + // the function. So create new entry basic block to serve as source + // for old entry's initial phi node. + if (srcB == T.getEntryBasicBlock ()) { + BasicBlock *FEntry = new BasicBlock ("entryfixup", dstB); + FEntry->getInstList ().push_back (new BranchInst (dstB)); + // Replace the references to the trace's predecessor with a + // reference to FEntry now. This is kind of a dodge because we + // don't have a pointer to the trace's predecessor, so we have + // to guess which one it is. Assume it's any phi value source in + // the entry BB which is not in the trace. + for (BasicBlock::iterator BI = srcB->begin (); + PHINode *PN = dyn_cast (BI); ++BI) + for (unsigned i = 0; i < PN->getNumIncomingValues (); ++i) + if (!T.contains (PN->getIncomingBlock (i))) { + // FIXME: Assert that O2CMap[PN]'s value i is live in. + Value *V = O2CMap[PN]; + assert (V && "Can't find clone of Phi node from trace entry BB"); + PHINode *PNinF = dyn_cast (V); + assert (PNinF + && "Clone of Phi node from entry BB is not a Phi node"); + PNinF->setIncomingBlock (i, FEntry); + } + } + + // If srcB contains a trace-exiting branch B, fix up B's clone in + // dstB to point to a new basic block in F that contains a return + // statement. Each return statement in F corresponds to a unique + // exit branch in T, and each return statement is numbered. + if (BranchInst *BI = containsTraceExitingBranch (srcB, T)) { + // Fix up this exit branch. + Value *V = O2CMap[BI]; + assert(V && isa (V) + && "Trace-exiting branch's clone is null, or not a branch?"); + BranchInst *BIinF = cast (V); + for (unsigned i = 0; i < BI->getNumSuccessors (); ++i) { + if (!T.contains (BI->getSuccessor (i))) { + // This is a trace-exiting destination of branch BI. Create a new + // basic block FB for its destination in the function. + std::string name ("exitfixup" + utostr (BranchNumber[BI]) + "_" + + utostr (i)); + BasicBlock *FB = new BasicBlock (name, F); + // Change BI's clone's destination to FB. + BIinF->setSuccessor (i, FB); + // Add the getelementptr/store instruction pairs here that + // correspond to each live-out variable. + unsigned Slot = 0; + for (LiveVariableSet::iterator SI = So.begin (), SE = So.end (); + SI != SE; ++SI) { + std::vector Index; + Index.push_back (Constant::getNullValue (Type::LongTy)); //long 0 + Index.push_back (ConstantUInt::get (Type::UByteTy, Slot));//ubyte Slot + DEBUG(std::cerr << "About to make a GEP: " << getFunctionArg (F, 0)); + for (std::vector::iterator VI = Index.begin(), + VE = Index.end (); VI != VE; ++VI) { + DEBUG(std::cerr << ", " << **VI); + } + DEBUG(std::cerr << "\n"); + GetElementPtrInst *GEP = + new GetElementPtrInst (getFunctionArg (F, 0), Index, + "liveOutP" + utostr (BranchNumber[BI]) + + "_" + utostr (i) + "_" + utostr (Slot)); + FB->getInstList ().push_back (GEP); + FB->getInstList ().push_back (new StoreInst (*SI, GEP)); + ++Slot; + } + // Make FB contain a return instruction that returns the + // number of the taken exit-branch. Add it to the end of FB: + // (FIXME: Numbering the branches in this way is probably + // unnecessary except in DEBUG mode.) + FB->getInstList ().push_back + (new ReturnInst (ConstantUInt::get (Type::UIntTy, + BranchNumber[BI]))); + } else { + // This is a non-trace-exiting destination of branch BI. Fix up + // its clone's destination to point to its successor's clone. + Value *V2 = O2CMap[BI->getSuccessor (i)]; + DEBUG(if (!V2) { + std::cerr + << "I'm confused: saw non-trace-exiting dest. of branch " + << *BI << " whose clone is " << *BIinF + << " successor number is " << i << " and successor is " + << *BI->getSuccessor (i) << ", but where's its clone?\n"; + assert(V2 && "Clone of basic block on trace is null?"); + }); + assert(isa (V2) + && "Clone of basic block on trace is not a basic block?"); + BasicBlock *BIsuccInF = cast (V2); + BIinF->setSuccessor (i, BIsuccInF); + } + } + } + + // Fix up operands of each instruction: + for (BasicBlock::iterator BI = dstB->begin (), BE = dstB->end (); + BI != BE; ++BI) { + Instruction &I = *BI; + for (unsigned i = 0; i < I.getNumOperands (); ++i) { + Value *V = I.getOperand (i); + // If the instruction I has an operand which is in the live-in + // set of the trace, then we must replace that operand with + // the corresponding argument of F. We can find out which + // operands to replace by looking them up in + // LiveInToParameterMap. + if (LiveInToParameterMap.find (V) != LiveInToParameterMap.end ()) { + DEBUG(std::cerr << *V << " in instruction " << I + << " is argument " << LiveInToParameterMap[V] + << " in new function\n"); + assert (V->getType () == + getFunctionArg (F, LiveInToParameterMap[V])->getType () + && "Live-in Value's type doesn't match corresponding arg type"); + I.setOperand(i, getFunctionArg (F, LiveInToParameterMap[V])); + } + // If the instruction I has an operand which is in the + // trace, that operand will have been cloned into the + // function, and I will still reference the version from + // outside the function. Replace any reference to an operand + // which has had a clone made with a reference to its clone. + else if (O2CMap.find (V) != O2CMap.end ()) { + DEBUG(std::cerr << *V << " in instruction " << I + << " is value " << O2CMap[V] << " in new function\n"); + assert (V->getType () == O2CMap[V]->getType () + && "Value's type doesn't match clone's type"); + I.setOperand(i, O2CMap[V]); + } + } + // Make sure that our operand fixups did the Right Thing for + // branches. + DEBUG(if (BranchInst *BrI = dyn_cast (&I)) { + for (unsigned i = 0; i < BrI->getNumSuccessors (); ++i) { + assert (BrI->getSuccessor (i)->getParent () == F + && "Branch out of function missed by copyTraceToFunction"); + assert (!O2CMap[BrI->getSuccessor (i)] + && "Branch's clone found as key in original-->clone map; " + "no one told me today was opposite day!"); + } + }); + } + + // Fix up Phi nodes: + for (BasicBlock::iterator BI = dstB->begin (), BE = dstB->end (); + BI != BE; ++BI) { + Instruction &I = *BI; + // In all cases, if a Phi node source in T was an on-trace basic + // block, then it will already have been fixed up to point to + // that block's clone, so we find off-trace sources by looking + // for source BBs which are not in F. + if (PHINode *PN = dyn_cast (&I)) { + unsigned onTraceSources = 0; + int lastSrcFound = -1; + for (unsigned i = 0; i < PN->getNumIncomingValues (); ++i) + if (PN->getIncomingBlock (i)->getParent () == F) { + lastSrcFound = i; + ++onTraceSources; + } + // Case 0. If it has 0 sources on the trace, that should really + // never happen. + assert (onTraceSources != 0 + && "Phi node on trace has ALL its sources from off-trace!"); + // Case 1. If it has 1 source S on the trace, replace its uses + // with S. + if (onTraceSources == 1) { + DEBUG(std::cerr << "Replacing Phi node" << *PN + << " with its lone on-trace input " + << *PN->getIncomingValue (lastSrcFound) << "\n"); + PN->replaceAllUsesWith (PN->getIncomingValue (lastSrcFound)); + dstB->getInstList ().erase (BI); // Delete the non-used Phi node + } else { + // Case N. If it has >1 source on the trace, just delete + // sources from the Phi node that are not on the trace. + int lastOffTraceSrcFound = -1; + do { + for (unsigned i = 0; i < PN->getNumIncomingValues (); ++i) + if (PN->getIncomingBlock (i)->getParent () != F) { + lastOffTraceSrcFound = i; // Found an off-trace source. + break; + } + if (lastOffTraceSrcFound != -1) { // Found one? + DEBUG(std::cerr << "Removing off-trace input " + << *PN->getIncomingValue (lastOffTraceSrcFound) + << " from Phi node " << *PN << "\n"); + PN->removeIncomingValue (lastOffTraceSrcFound); // Delete it. + } + } while (lastOffTraceSrcFound != -1); // Continue until none found. + } + } + // Make sure that our Phi fixups did the Right Thing. + DEBUG(if (PHINode *PN = dyn_cast (&I)) + for (unsigned i = 0; i < PN->getNumIncomingValues (); ++i) + assert (PN->getIncomingBlock (i)->getParent () == F && + "Sorry, copyTraceIntoFunction mishandled a Phi node")); + } + + // Remove calls to first-level instrumentation if we find them. + for (BasicBlock::iterator BI = dstB->begin (), BE = dstB->end (); + BI != BE; ++BI) { + Instruction &I = *BI; + if (CallInst *CI = dyn_cast (&I)) { + Function *CF = CI->getCalledFunction (); + if (CF->getName () == "llvm_first_trigger" && CF->isExternal ()) { + DEBUG(std::cerr << " (Found a call instruction " << *CI + << " ... Smells like llvm_first_trigger.)\n"); + dstB->getInstList ().erase (BI); + } + } + } + } + + Function *TraceToFunction::traceToFunction (Trace &T) { + std::string CurrentFnName = T.getFunction ()->getName (); + DEBUG(std::cerr << "In traceToFunction() for " << CurrentFnName << "\n"); + + // Get some information about the trace's relationship to its parent + // function. + LiveVariableSet Si = getTraceLiveInSet (T); + LiveVariableSet So = getTraceLiveOutSet (T); + TypeVector P = createFunctionArgTypeVector (createLiveOutType (So), Si); + + // Make a new internal Function with return type int and parameter + // list P, in the same Module as the trace's parent function. + std::string name (CurrentFnName + ".trace"); + Function *F = new Function (FunctionType::get (Type::UIntTy, P, false), + GlobalValue::InternalLinkage, name, + T.getModule ()); + DEBUG(giveNamesToFunctionArgs (Si, F)); + fillInFunctionBody (T, F, So); + return F; + } + + /// runTraceToFunction - Entry point for TraceToFunction transformation. + + Function *runTraceToFunction (Trace &T) { + TraceToFunction TTF; + return TTF.traceToFunction (T); + } + From lattner at cs.uiuc.edu Thu Aug 28 14:57:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 14:57:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CWriter/Writer.cpp Message-ID: <200308281956.OAA18462@apoc.cs.uiuc.edu> Changes in directory llvm/lib/CWriter: Writer.cpp updated: 1.119 -> 1.120 --- Log message: Fix really nasty bugs in the CWriter, handling invoke instructions. Tracking these down was NOT phun. --- Diffs of the changes: Index: llvm/lib/CWriter/Writer.cpp diff -u llvm/lib/CWriter/Writer.cpp:1.119 llvm/lib/CWriter/Writer.cpp:1.120 --- llvm/lib/CWriter/Writer.cpp:1.119 Sun Aug 24 16:00:22 2003 +++ llvm/lib/CWriter/Writer.cpp Thu Aug 28 14:56:10 2003 @@ -894,7 +894,8 @@ UI != UE; ++UI) if (TerminatorInst *TI = dyn_cast(*UI)) if (TI != Prev->getTerminator() || - isa(Prev->getTerminator())) { + isa(Prev->getTerminator()) || + isa(Prev->getTerminator())) { NeedsLabel = true; break; } @@ -968,6 +969,8 @@ Out << " }\n" << " __llvm_jmpbuf_list = &Entry;\n" << " "; + + if (II.getType() != Type::VoidTy) outputLValue(&II); visitCallSite(&II); Out << ";\n" << " __llvm_jmpbuf_list = Entry.next;\n" @@ -998,7 +1001,7 @@ Out << "; /* for PHI node */\n"; } - if (CurBB->getNext() != Succ) { + if (CurBB->getNext() != Succ || isa(CurBB->getTerminator())) { Out << std::string(Indent, ' ') << " goto "; writeOperand(Succ); Out << ";\n"; From lattner at cs.uiuc.edu Thu Aug 28 14:58:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 14:58:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/EH/Makefile Message-ID: <200308281957.OAA18759@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend/EH: Makefile updated: 1.1 -> 1.2 --- Log message: Link to the C++ libraries. This is temporary --- Diffs of the changes: Index: llvm/test/Regression/C++Frontend/EH/Makefile diff -u llvm/test/Regression/C++Frontend/EH/Makefile:1.1 llvm/test/Regression/C++Frontend/EH/Makefile:1.2 --- llvm/test/Regression/C++Frontend/EH/Makefile:1.1 Sun Aug 24 07:27:53 2003 +++ llvm/test/Regression/C++Frontend/EH/Makefile Thu Aug 28 14:57:14 2003 @@ -8,3 +8,5 @@ LEVEL = ../../../.. include $(LEVEL)/test/Programs/SingleSource/Makefile.singlesrc +## These should eventually be automatic! +LIBS := -lexception -lsupc++ \ No newline at end of file From lattner at cs.uiuc.edu Thu Aug 28 14:59:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 14:59:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/EH/exception_spec_test.cpp simple_rethrow.cpp Message-ID: <200308281958.OAA18774@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend/EH: exception_spec_test.cpp added (r1.1) simple_rethrow.cpp added (r1.1) --- Log message: New testcases, all of which work with llvmg++! This tests exception specifications, and also adds an "easy" rethrow test. --- Diffs of the changes: Index: llvm/test/Regression/C++Frontend/EH/exception_spec_test.cpp diff -c /dev/null llvm/test/Regression/C++Frontend/EH/exception_spec_test.cpp:1.1 *** /dev/null Thu Aug 28 14:58:03 2003 --- llvm/test/Regression/C++Frontend/EH/exception_spec_test.cpp Thu Aug 28 14:57:53 2003 *************** *** 0 **** --- 1,51 ---- + // This tests that exception specifications interact properly with unexpected + // handlers. + + #include + #include + #include + + static void TerminateHandler() { + printf("std::terminate called\n"); + exit(1); + } + + static void UnexpectedHandler1() { + printf("std::unexpected called: throwing a double\n"); + throw 1.0; + } + + static void UnexpectedHandler2() { + printf("std::unexpected called: throwing an int!\n"); + throw 1; + } + + void test(bool Int) throw (double) { + if (Int) { + printf("Throwing an int from a function which only allows doubles!\n"); + throw 1; + } else { + printf("Throwing a double from a function which allows doubles!\n"); + throw 1.0; + } + } + + int main() { + try { + test(false); + } catch (double D) { + printf("Double successfully caught!\n"); + } + + std::set_terminate(TerminateHandler); + std::set_unexpected(UnexpectedHandler1); + + try { + test(true); + } catch (double D) { + printf("Double successfully caught!\n"); + } + + std::set_unexpected(UnexpectedHandler2); + test(true); + } Index: llvm/test/Regression/C++Frontend/EH/simple_rethrow.cpp diff -c /dev/null llvm/test/Regression/C++Frontend/EH/simple_rethrow.cpp:1.1 *** /dev/null Thu Aug 28 14:58:03 2003 --- llvm/test/Regression/C++Frontend/EH/simple_rethrow.cpp Thu Aug 28 14:57:53 2003 *************** *** 0 **** --- 1,25 ---- + #include + + int throws() { + printf("Throwing int\n"); + throw 16; + }; + + int callsthrows() { + try { + throws(); + } catch (...) { + printf("Caught something, rethrowing...\n"); + throw; + } + } + + int main() { + try { + callsthrows(); + } catch (int i) { + printf("Caught int: %d\n", i); + return i-16; + } + return 1; + } From lattner at cs.uiuc.edu Thu Aug 28 15:00:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 15:00:01 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/c++-exception.cpp c++-exception.h exception.h Message-ID: <200308281959.OAA18789@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: c++-exception.cpp updated: 1.5 -> 1.6 c++-exception.h updated: 1.6 -> 1.7 exception.h updated: 1.3 -> 1.4 --- Log message: * Add proper support for rethrown exceptions. * Make catch_begin() produce a pointer that must be passed to catch_end() * Eliminate the caught exception stack. * Add optional debugging code that may be turned on. --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/c++-exception.cpp diff -u llvm/runtime/GCCLibraries/libexception/c++-exception.cpp:1.5 llvm/runtime/GCCLibraries/libexception/c++-exception.cpp:1.6 --- llvm/runtime/GCCLibraries/libexception/c++-exception.cpp:1.5 Thu Aug 28 09:35:52 2003 +++ llvm/runtime/GCCLibraries/libexception/c++-exception.cpp Thu Aug 28 14:58:51 2003 @@ -11,6 +11,12 @@ #include #include +//#define DEBUG + +#ifdef DEBUG +#include +#endif + //===----------------------------------------------------------------------===// // Generic exception support // @@ -18,7 +24,11 @@ // Thread local state for exception handling. // FIXME: This should really be made thread-local! // -static llvm_exception *CaughtExceptionStack = 0; + +// LastCaughtException - The last exception caught by this handler. This is for +// implementation of _rethrow and _get_last_caught. +// +static llvm_exception *LastCaughtException = 0; // UncaughtExceptionStack - The stack of exceptions currently being thrown. static llvm_exception *UncaughtExceptionStack = 0; @@ -76,13 +86,9 @@ // exception. // static void cxx_destructor(llvm_exception *LE) /* might throw */{ + assert(LE->Next == 0 && "On the uncaught stack??"); llvm_cxx_exception *E = get_cxx_exception(LE); - // The exception is no longer caught. - assert(CaughtExceptionStack == LE && - "Destroying an exception which is not the current caught exception?"); - CaughtExceptionStack = LE->Next; - struct ExceptionFreer { void *Ptr; ExceptionFreer(void *P) : Ptr(P) {} @@ -110,6 +116,7 @@ E->BaseException.Next = UncaughtExceptionStack; UncaughtExceptionStack = &E->BaseException; E->BaseException.HandlerCount = 0; + E->BaseException.isRethrown = 0; E->TypeInfo = (const std::type_info*)TypeInfoPtr; E->ExceptionObjectDestructor = DtorPtr; @@ -121,14 +128,16 @@ // CXXExceptionISA - use the type info object stored in the exception to see if // TypeID matches and, if so, to adjust the exception object pointer. // -static void *CXXExceptionISA(llvm_cxx_exception *E, const std::type_info *Type){ +static void *CXXExceptionISA(llvm_cxx_exception *E, + const std::type_info *Type) throw() { // ThrownPtr is a pointer to the object being thrown... void *ThrownPtr = E+1; const std::type_info *ThrownType = E->TypeInfo; +#if 0 // FIXME: this code exists in the GCC exception handling library: I haven't // thought about this yet, so it should be verified at some point! -#if 1 + // Pointer types need to adjust the actual pointer, not // the pointer to pointer that is the exception object. // This also has the effect of passing pointer types @@ -137,8 +146,13 @@ ThrownPtr = *(void **)ThrownPtr; #endif - if (Type->__do_catch(ThrownType, &ThrownPtr, 1)) + if (Type->__do_catch(ThrownType, &ThrownPtr, 1)) { +#ifdef DEBUG + printf("isa<%s>(%s): 0x%p -> 0x%p\n", Type->name(), ThrownType->name(), + E+1, ThrownPtr); +#endif return ThrownPtr; + } return 0; } @@ -175,11 +189,17 @@ UncaughtExceptionStack = E->Next; // The exception is now caught. - E->Next = CaughtExceptionStack; - CaughtExceptionStack = E; + LastCaughtException = E; + E->Next = 0; + E->isRethrown = 0; // Increment the handler count for this exception. E->HandlerCount++; + +#ifdef DEBUG + printf("Exiting begin_catch Ex=0x%p HandlerCount=%d!\n", E+1, + E->HandlerCount); +#endif // Return a pointer to the raw exception object. return E+1; @@ -200,22 +220,44 @@ return ObjPtr; } +// __llvm_cxxeh_get_last_caught - Return the last exception that was caught by +// ...begin_catch. +// +void *__llvm_cxxeh_get_last_caught() throw() { + assert(LastCaughtException && "No exception caught!!"); + return LastCaughtException+1; +} // __llvm_cxxeh_end_catch - This function decrements the HandlerCount of the // top-level caught exception, destroying it if this is the last handler for the // exception. // -void __llvm_cxxeh_end_catch() /* might throw */ { - llvm_exception *E = CaughtExceptionStack; +void __llvm_cxxeh_end_catch(void *Ex) /* might throw */ { + llvm_exception *E = (llvm_exception*)Ex - 1; assert(E && "There are no caught exceptions!"); // If this is the last handler using the exception, destroy it now! - if (--E->HandlerCount == 0) + if (--E->HandlerCount == 0 && !E->isRethrown) { +#ifdef DEBUG + printf("Destroying exception!\n"); +#endif E->ExceptionDestructor(E); // Release memory for the exception + } +#ifdef DEBUG + printf("Exiting end_catch Ex=0x%p HandlerCount=%d!\n", Ex, E->HandlerCount); +#endif } +// __llvm_cxxeh_call_terminate - This function is called when the dtor for an +// object being destroyed due to an exception throw throws an exception. This +// is illegal because it would cause multiple exceptions to be active at one +// time. void __llvm_cxxeh_call_terminate() throw() { - __terminate(__terminate_handler); + void (*Handler)(void) = __terminate_handler; + if (UncaughtExceptionStack) + if (UncaughtExceptionStack->ExceptionType == CXXException) + Handler = get_cxx_exception(UncaughtExceptionStack)->TerminateHandler; + __terminate(Handler); } @@ -225,19 +267,21 @@ // prepared to deal with foreign exceptions. // void __llvm_cxxeh_rethrow() throw() { - llvm_exception *E = CaughtExceptionStack; + llvm_exception *E = LastCaughtException; if (E == 0) - // 15.1.8 - If there are no uncaught exceptions being thrown, 'throw;' - // should call terminate. + // 15.1.8 - If there are no exceptions being thrown, 'throw;' should call + // terminate. // __terminate(__terminate_handler); - // Otherwise we have an exception to rethrow. Move it back to the uncaught - // stack. - CaughtExceptionStack = E->Next; + // Otherwise we have an exception to rethrow. Mark the exception as such. + E->isRethrown = 1; + + // Add the exception to the top of the uncaught stack, to preserve the + // invariant that the top of the uncaught stack is the current exception. E->Next = UncaughtExceptionStack; UncaughtExceptionStack = E; - + // Return to the caller, which should perform the unwind now. } @@ -283,8 +327,8 @@ // Whatever exception this is, it is not allowed by the (empty) spec, call // unexpected, according to 15.4.8. try { - __llvm_cxxeh_begin_catch(); // Start the catch - __llvm_cxxeh_end_catch(); // Free the exception + void *Ex = __llvm_cxxeh_begin_catch(); // Start the catch + __llvm_cxxeh_end_catch(Ex); // Free the exception __unexpected(__unexpected_handler); } catch (...) { // Any exception thrown by unexpected cannot match the ehspec. Call @@ -307,10 +351,10 @@ // permitted to pass through) or not a C++ exception that is allowed. Kill // the exception and call the unexpected handler. try { - __llvm_cxxeh_begin_catch(); // Start the catch - __llvm_cxxeh_end_catch(); // Free the exception + void *Ex = __llvm_cxxeh_begin_catch(); // Start the catch + __llvm_cxxeh_end_catch(Ex); // Free the exception } catch (...) { - __terminate(__terminate_handler); // Exception dtor threw + __terminate(__terminate_handler); // Exception dtor threw } try { Index: llvm/runtime/GCCLibraries/libexception/c++-exception.h diff -u llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.6 llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.7 --- llvm/runtime/GCCLibraries/libexception/c++-exception.h:1.6 Thu Aug 28 09:43:36 2003 +++ llvm/runtime/GCCLibraries/libexception/c++-exception.h Thu Aug 28 14:58:51 2003 @@ -55,7 +55,7 @@ namespace __cxxabiv1 { // Invokes given handler, dying appropriately if the user handler was // so inconsiderate as to return. - extern void __terminate(std::terminate_handler) __attribute__((noreturn)); + extern void __terminate(std::terminate_handler) throw() __attribute__((noreturn)); extern void __unexpected(std::unexpected_handler) __attribute__((noreturn)); // The current installed user handlers. @@ -74,8 +74,10 @@ throw(); void *__llvm_cxxeh_begin_catch() throw(); void *__llvm_cxxeh_begin_catch_if_isa(void *CatchType) throw(); - void __llvm_cxxeh_end_catch() /* might throw */; + void __llvm_cxxeh_end_catch(void *Exception) /* might throw */; void __llvm_cxxeh_rethrow() throw(); + void *__llvm_cxxeh_get_last_caught() throw(); + void __llvm_cxxeh_check_eh_spec(void *Info, ...); } Index: llvm/runtime/GCCLibraries/libexception/exception.h diff -u llvm/runtime/GCCLibraries/libexception/exception.h:1.3 llvm/runtime/GCCLibraries/libexception/exception.h:1.4 --- llvm/runtime/GCCLibraries/libexception/exception.h:1.3 Wed Aug 27 17:58:51 2003 +++ llvm/runtime/GCCLibraries/libexception/exception.h Thu Aug 28 14:58:51 2003 @@ -31,6 +31,14 @@ // falls to zero, the exception is destroyed. // unsigned HandlerCount; + + // isRethrown - This field is set on an exception if it has been 'throw;'n. + // This is needed because the exception might exit through a number of the + // end_catch statements matching the number of begin_catch statements that + // have been processed. When this happens, the exception should become + // uncaught, not dead. + // + int isRethrown; }; enum { From lattner at cs.uiuc.edu Thu Aug 28 15:33:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 15:33:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/EH/function_try_block.cpp Message-ID: <200308282032.PAA21216@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend/EH: function_try_block.cpp added (r1.1) --- Log message: Add test for the last chapter of our C++ exception handling odyssey. llvmg++ now fully supports all C++ exception handling functionality. --- Diffs of the changes: Index: llvm/test/Regression/C++Frontend/EH/function_try_block.cpp diff -c /dev/null llvm/test/Regression/C++Frontend/EH/function_try_block.cpp:1.1 *** /dev/null Thu Aug 28 15:32:46 2003 --- llvm/test/Regression/C++Frontend/EH/function_try_block.cpp Thu Aug 28 15:32:36 2003 *************** *** 0 **** --- 1,55 ---- + + #include + + static unsigned NumAs = 0; + + struct A { + unsigned ANum; + A() : ANum(NumAs++) { printf("Created A #%d\n", ANum); } + A(const A &a) : ANum(NumAs++) { printf("Copy Created A #%d\n", ANum); } + ~A() { printf("Destroyed A #%d\n", ANum); } + }; + + static bool ShouldThrow = false; + + int throws() + try + { + if (ShouldThrow) throw 7; return 123; + } catch (...) { + printf("'throws' threw an exception: rethrowing!\n"); + throw; + } + + struct B { + A a0, a1, a2; + int i; + A a3, a4; + + B(); + ~B() { printf("B destructor!\n"); } + }; + + B::B() + try + : i(throws()) + { + printf("In B constructor!\n"); + } + catch (int i) { + printf("In B catch block with int %d: auto rethrowing\n", i); + } + + + int main() { + { + B b; // Shouldn't throw. + } + + try { + ShouldThrow = true; + B b; + } catch (...) { + printf("Caught exception!\n"); + } + } From lattner at cs.uiuc.edu Thu Aug 28 15:34:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 15:34:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/EH/ctor_dtor_count.cpp Message-ID: <200308282033.PAA21301@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend/EH: ctor_dtor_count.cpp added (r1.1) --- Log message: Add another testcase I found lying around. --- Diffs of the changes: Index: llvm/test/Regression/C++Frontend/EH/ctor_dtor_count.cpp diff -c /dev/null llvm/test/Regression/C++Frontend/EH/ctor_dtor_count.cpp:1.1 *** /dev/null Thu Aug 28 15:33:56 2003 --- llvm/test/Regression/C++Frontend/EH/ctor_dtor_count.cpp Thu Aug 28 15:33:46 2003 *************** *** 0 **** --- 1,23 ---- + #include + + static int c; + + struct A { + A() { ++c; } + A(const A&) { ++c; } + ~A() { --c; } + }; + + struct B { + A a; + B() { A a; throw 1; } + }; + + int main() { + try { + B b; + } catch (...) {} + if (!c) printf("All ok!\n"); + return c; + } + From lattner at cs.uiuc.edu Thu Aug 28 16:24:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 16:24:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200308282123.QAA27432@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.123 -> 1.124 --- Log message: Add support for the llvm.unwind intrinsic, which we codegen to just do an abort until we implement unwinding. Add support for the invoke instruction, which codegens just like a call with a branch after it. The end effect of this change is that programs using the invoke instruction, but never unwinding, will work fine. Programs that unwind will abort until we get unwind support. --- Diffs of the changes: Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.123 llvm/lib/Target/X86/InstSelectSimple.cpp:1.124 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.123 Sun Aug 24 14:19:47 2003 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Thu Aug 28 16:23:43 2003 @@ -131,6 +131,7 @@ void doCall(const ValueRecord &Ret, MachineInstr *CallMI, const std::vector &Args); void visitCallInst(CallInst &I); + void visitInvokeInst(InvokeInst &II); void visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &I); // Arithmetic operators @@ -994,6 +995,32 @@ doCall(ValueRecord(DestReg, CI.getType()), TheCall, Args); } + +// visitInvokeInst - For now, we don't support the llvm.unwind intrinsic, so +// invoke's are just calls with an unconditional branch after them! +void ISel::visitInvokeInst(InvokeInst &II) { + MachineInstr *TheCall; + if (Function *F = II.getCalledFunction()) { + // Emit a CALL instruction with PC-relative displacement. + TheCall = BuildMI(X86::CALLpcrel32, 1).addGlobalAddress(F, true); + } else { // Emit an indirect call... + unsigned Reg = getReg(II.getCalledValue()); + TheCall = BuildMI(X86::CALLr32, 1).addReg(Reg); + } + + std::vector Args; + for (unsigned i = 3, e = II.getNumOperands(); i != e; ++i) + Args.push_back(ValueRecord(II.getOperand(i))); + + unsigned DestReg = II.getType() != Type::VoidTy ? getReg(II) : 0; + doCall(ValueRecord(DestReg, II.getType()), TheCall, Args); + + // If the normal destination is not the next basic block, emit a 'jmp'. + if (II.getNormalDest() != getBlockAfter(II.getParent())) + BuildMI(BB, X86::JMP, 1).addPCDisp(II.getNormalDest()); +} + + void ISel::visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &CI) { unsigned TmpReg1, TmpReg2; switch (ID) { @@ -1012,9 +1039,10 @@ addDirectMem(BuildMI(BB, X86::MOVrm32, 5), TmpReg2).addReg(TmpReg1); return; + case LLVMIntrinsic::unwind: // llvm.unwind is not supported yet! case LLVMIntrinsic::longjmp: case LLVMIntrinsic::siglongjmp: - BuildMI(X86::CALLpcrel32, 1).addExternalSymbol("abort", true); + BuildMI(BB, X86::CALLpcrel32, 1).addExternalSymbol("abort", true); return; case LLVMIntrinsic::setjmp: From brukman at cs.uiuc.edu Thu Aug 28 16:34:00 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 28 16:34:00 2003 Subject: [llvm-commits] CVS: llvm/tools/llvm-as/Makefile as.cpp Message-ID: <200308282133.QAA30782@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-as: Makefile updated: 1.10 -> 1.11 as.cpp updated: 1.20 -> 1.21 --- Log message: Renaming LLVM `as' to `llvm-as'. --- Diffs of the changes: Index: llvm/tools/llvm-as/Makefile diff -u llvm/tools/llvm-as/Makefile:1.10 llvm/tools/llvm-as/Makefile:1.11 --- llvm/tools/llvm-as/Makefile:1.10 Tue Jul 23 12:50:45 2002 +++ llvm/tools/llvm-as/Makefile Thu Aug 28 16:32:57 2003 @@ -1,5 +1,5 @@ LEVEL = ../.. -TOOLNAME = as +TOOLNAME = llvm-as USEDLIBS = asmparser bcwriter vmcore support.a include $(LEVEL)/Makefile.common Index: llvm/tools/llvm-as/as.cpp diff -u llvm/tools/llvm-as/as.cpp:1.20 llvm/tools/llvm-as/as.cpp:1.21 --- llvm/tools/llvm-as/as.cpp:1.20 Mon Aug 18 15:47:13 2003 +++ llvm/tools/llvm-as/as.cpp Thu Aug 28 16:32:57 2003 @@ -2,10 +2,10 @@ // LLVM 'AS' UTILITY // // This utility may be invoked in the following manner: -// as --help - Output information about command line switches -// as [options] - Read LLVM assembly from stdin, write bytecode to stdout -// as [options] x.ll - Read LLVM assembly from the x.ll file, write bytecode -// to the x.bc file. +// llvm-as --help - Output information about command line switches +// llvm-as [options] - Read LLVM asm from stdin, write bytecode to stdout +// llvm-as [options] x.ll - Read LLVM asm from the x.ll file, write bytecode +// to the x.bc file. // //===------------------------------------------------------------------------=== From brukman at cs.uiuc.edu Thu Aug 28 16:35:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 28 16:35:01 2003 Subject: [llvm-commits] CVS: llvm/tools/llvm-dis/Makefile dis.cpp Message-ID: <200308282134.QAA30808@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-dis: Makefile updated: 1.10 -> 1.11 dis.cpp updated: 1.31 -> 1.32 --- Log message: Renaming LLVM `dis' to `llvm-dis'. --- Diffs of the changes: Index: llvm/tools/llvm-dis/Makefile diff -u llvm/tools/llvm-dis/Makefile:1.10 llvm/tools/llvm-dis/Makefile:1.11 --- llvm/tools/llvm-dis/Makefile:1.10 Fri Aug 8 10:37:35 2003 +++ llvm/tools/llvm-dis/Makefile Thu Aug 28 16:34:13 2003 @@ -1,5 +1,5 @@ LEVEL = ../.. -TOOLNAME = dis +TOOLNAME = llvm-dis USEDLIBS = bcreader cwriter ipa.a vmcore support.a include $(LEVEL)/Makefile.common Index: llvm/tools/llvm-dis/dis.cpp diff -u llvm/tools/llvm-dis/dis.cpp:1.31 llvm/tools/llvm-dis/dis.cpp:1.32 --- llvm/tools/llvm-dis/dis.cpp:1.31 Sat May 31 16:47:16 2003 +++ llvm/tools/llvm-dis/dis.cpp Thu Aug 28 16:34:13 2003 @@ -2,9 +2,9 @@ // LLVM 'DIS' UTILITY // // This utility may be invoked in the following manner: -// dis [options] - Read LLVM bytecode from stdin, write assembly to stdout -// dis [options] x.bc - Read LLVM bytecode from the x.bc file, write assembly -// to the x.ll file. +// llvm-dis [options] - Read LLVM bytecode from stdin, write asm to stdout +// llvm-dis [options] x.bc - Read LLVM bytecode from the x.bc file, write asm +// to the x.ll file. // Options: // --help - Output information about command line switches // -c - Print C code instead of LLVM assembly @@ -39,8 +39,7 @@ static cl::opt WriteMode(cl::desc("Specify the output format:"), - cl::values( - clEnumVal(llvm, "Output LLVM assembly"), + cl::values(clEnumVal(llvm, "Output LLVM assembly"), clEnumVal(c , "Output C code for program"), 0)); From criswell at cs.uiuc.edu Thu Aug 28 16:43:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 28 16:43:01 2003 Subject: [llvm-commits] CVS: llvm/tools/llc/llc.cpp Message-ID: <200308282142.QAA23294@choi.cs.uiuc.edu> Changes in directory llvm/tools/llc: llc.cpp updated: 1.82 -> 1.83 --- Log message: Added code to avoid checking for .bc when the filename is too short. --- Diffs of the changes: Index: llvm/tools/llc/llc.cpp diff -u llvm/tools/llc/llc.cpp:1.82 llvm/tools/llc/llc.cpp:1.83 --- llvm/tools/llc/llc.cpp:1.82 Sun Aug 24 14:50:12 2003 +++ llvm/tools/llc/llc.cpp Thu Aug 28 16:42:29 2003 @@ -44,7 +44,8 @@ std::string IFN = InputFilename; std::string outputFilename; int Len = IFN.length(); - if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') { + if ((Len > 2) && + IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') { outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/ } else { outputFilename = IFN; From criswell at cs.uiuc.edu Thu Aug 28 16:44:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Thu Aug 28 16:44:01 2003 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/InstrSched/SchedGraph.cpp Message-ID: <200308282143.QAA23311@choi.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/InstrSched: SchedGraph.cpp updated: 1.49 -> 1.50 --- Log message: Fixed two double free bugs that caused llc to segfault or run forever. --- Diffs of the changes: Index: llvm/lib/CodeGen/InstrSched/SchedGraph.cpp diff -u llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.49 llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.50 --- llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.49 Thu Aug 28 10:30:40 2003 +++ llvm/lib/CodeGen/InstrSched/SchedGraph.cpp Thu Aug 28 16:43:17 2003 @@ -53,10 +53,18 @@ } } +// +// Method: SchedGraphNode Destructor +// +// Description: +// Free memory allocated by the SchedGraphNode object. +// +// Notes: +// Do not delete the edges here. The base class will take care of that. +// Only handle subclass specific stuff here (where currently there is +// none). +// SchedGraphNode::~SchedGraphNode() { - // for each node, delete its out-edges - std::for_each(beginOutEdges(), endOutEdges(), - deleter); } // @@ -67,11 +75,19 @@ buildGraph(target); } +// +// Method: SchedGraph Destructor +// +// Description: +// This method deletes memory allocated by the SchedGraph object. +// +// Notes: +// Do not delete the graphRoot or graphLeaf here. The base class handles +// that bit of work. +// SchedGraph::~SchedGraph() { for (const_iterator I = begin(); I != end(); ++I) delete I->second; - delete graphRoot; - delete graphLeaf; } void SchedGraph::dump() const { From brukman at cs.uiuc.edu Thu Aug 28 16:45:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 28 16:45:01 2003 Subject: [llvm-commits] CVS: llvm/tools/Makefile Message-ID: <200308282144.QAA30870@zion.cs.uiuc.edu> Changes in directory llvm/tools: Makefile updated: 1.19 -> 1.20 --- Log message: Build llvm-as and llvm-dis as the upgrade path to renamed tools. --- Diffs of the changes: Index: llvm/tools/Makefile diff -u llvm/tools/Makefile:1.19 llvm/tools/Makefile:1.20 --- llvm/tools/Makefile:1.19 Wed May 14 16:31:31 2003 +++ llvm/tools/Makefile Thu Aug 28 16:43:51 2003 @@ -1,5 +1,6 @@ LEVEL := .. -PARALLEL_DIRS := as dis opt gccas llc link lli gccld analyze extract bugpoint +PARALLEL_DIRS := as llvm-as dis llvm-dis opt gccas llc link lli gccld \ + analyze extract bugpoint include $(LEVEL)/Makefile.common From brukman at cs.uiuc.edu Thu Aug 28 16:46:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 28 16:46:01 2003 Subject: [llvm-commits] CVS: llvm/Makefile.common Message-ID: <200308282145.QAA30899@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.common updated: 1.129 -> 1.130 --- Log message: Start using `llvm-as' instead of `as'. --- Diffs of the changes: Index: llvm/Makefile.common diff -u llvm/Makefile.common:1.129 llvm/Makefile.common:1.130 --- llvm/Makefile.common:1.129 Wed Aug 27 13:26:44 2003 +++ llvm/Makefile.common Thu Aug 28 16:45:08 2003 @@ -332,7 +332,7 @@ # Some of the compiled LLVM tools which are used for compilation of runtime # libraries. # -LLVMAS := $(LLVMTOOLCURRENT)/as +LLVMAS := $(LLVMTOOLCURRENT)/llvm-as ########################################################################### From brukman at cs.uiuc.edu Thu Aug 28 16:47:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 28 16:47:01 2003 Subject: [llvm-commits] CVS: llvm/test/Scripts/as dis Message-ID: <200308282146.QAA30927@zion.cs.uiuc.edu> Changes in directory llvm/test/Scripts: as added (r1.1) dis added (r1.1) --- Log message: Near-term fix for renaming `as' -> `llvm-as' and `dis' -> `llvm-dis'. --- Diffs of the changes: Index: llvm/test/Scripts/as diff -c /dev/null llvm/test/Scripts/as:1.1 *** /dev/null Thu Aug 28 16:46:44 2003 --- llvm/test/Scripts/as Thu Aug 28 16:46:34 2003 *************** *** 0 **** --- 1,5 ---- + #!/bin/sh + # + # Run llvm-as with same arguments + # + llvm-as $* Index: llvm/test/Scripts/dis diff -c /dev/null llvm/test/Scripts/dis:1.1 *** /dev/null Thu Aug 28 16:46:44 2003 --- llvm/test/Scripts/dis Thu Aug 28 16:46:34 2003 *************** *** 0 **** --- 1,5 ---- + #!/bin/sh + # + # Run llvm-dis with same arguments + # + llvm-dis $* From brukman at cs.uiuc.edu Thu Aug 28 17:04:03 2003 From: brukman at cs.uiuc.edu (Michael Brukman) Date: Thu Aug 28 17:04:03 2003 Subject: [llvm-commits] CVS: llvm/www/docs/GettingStarted.html Message-ID: <200308282203.RAA20406@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: GettingStarted.html updated: 1.32 -> 1.33 --- Log message: Renaming `as' -> `llvm-as' and `dis' -> `llvm-dis'. --- Diffs of the changes: Index: llvm/www/docs/GettingStarted.html diff -u llvm/www/docs/GettingStarted.html:1.32 llvm/www/docs/GettingStarted.html:1.33 --- llvm/www/docs/GettingStarted.html:1.32 Mon Aug 11 14:13:12 2003 +++ llvm/www/docs/GettingStarted.html Thu Aug 28 17:02:50 2003 @@ -815,12 +815,12 @@ following is a brief introduction to the most important tools.

    -
    as
    The assembler transforms the human readable +
    llvm-as
    The assembler transforms the human readable LLVM assembly to LLVM bytecode.

    -

    dis
    The disassembler transforms the LLVM bytecode - to human readable LLVM assembly. Additionally it can convert LLVM - bytecode to C, which is enabled with the -c option.

    +

    llvm-dis
    The disassembler transforms the LLVM + bytecode to human readable LLVM assembly. Additionally it can convert + LLVM bytecode to C, which is enabled with the -c option.

    lli
    lli is the LLVM interpreter, which can directly execute LLVM bytecode (although very slowly...). In addition @@ -851,7 +851,7 @@ x.o file (which is an LLVM bytecode file that can be disassembled or manipulated just like any other bytecode file). The command line interface to gccas is designed to be as close as - possible to the system 'as' utility so that the gcc + possible to the system `as' utility so that the gcc frontend itself did not have to be modified to interface to a "weird" assembler.

    @@ -1035,10 +1035,10 @@ % lli hello.bc

    -

  • Use the dis utility to take a look at the LLVM assembly +
  • Use the llvm-dis utility to take a look at the LLVM assembly code:

    - % dis < hello.bc | less

    + % llvm-dis < hello.bc | less

  • Compile the program to native Sparc assembly using the code generator (assuming you are currently on a Sparc system):

    From lattner at cs.uiuc.edu Thu Aug 28 17:13:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 17:13:01 2003 Subject: [llvm-commits] CVS: llvm/www/docs/LangRef.html Message-ID: <200308282212.RAA22525@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: LangRef.html updated: 1.26 -> 1.27 --- Log message: Document the llvm.unwind intrinsic. Clarify the documentation for the invoke instruction --- Diffs of the changes: Index: llvm/www/docs/LangRef.html diff -u llvm/www/docs/LangRef.html:1.26 llvm/www/docs/LangRef.html:1.27 --- llvm/www/docs/LangRef.html:1.26 Mon Jul 14 12:20:40 2003 +++ llvm/www/docs/LangRef.html Thu Aug 28 17:12:25 2003 @@ -81,6 +81,7 @@

  • 'llvm.va_start' Intrinsic
  • 'llvm.va_end' Intrinsic
  • 'llvm.va_copy' Intrinsic +
  • 'llvm.unwind' Intrinsic @@ -741,13 +742,14 @@
    Overview:
    -The 'invoke' instruction is used to cause control flow to transfer to a -specified function, with the possibility of control flow transfer to either the -'normal label' label or the 'exception label'. The 'call' instruction is closely related, but guarantees -that control flow either never returns from the called function, or that it -returns to the instruction following the 'call' -instruction.

    +The 'invoke' instruction causes control to transfer to a specified +function, with the possibility of control flow transfer to either the +'normal label' label or the 'exception label'. If the callee +function invokes the "ret" instruction, control +flow will return to the "normal" label. If the callee (or any indirect callees) +calls the "llvm.unwind" intrinsic, control is +interrupted, and continued at the "except" label.

    +

    Arguments:
    @@ -757,7 +759,7 @@
  • 'ptr to function ty': shall be the signature of the pointer to function value being invoked. In most cases, this is a direct function invocation, but indirect invokes are just as possible, branching off -an arbitrary pointer to function value.

    +an arbitrary pointer to function value.

  • 'function ptr val': An LLVM value containing a pointer to a function to be invoked. @@ -769,26 +771,26 @@
  • 'normal label': the label reached when the called function executes a 'ret' instruction. -
  • 'exception label': the label reached when an exception is thrown. +
  • 'exception label': the label reached when a callee calls the llvm.unwind intrinsic.
    Semantics:
    This instruction is designed to operate as a standard 'call' instruction in most regards. The primary -difference is that it associates a label with the function invocation that may -be accessed via the runtime library provided by the execution environment. This -instruction is used in languages with destructors to ensure that proper cleanup -is performed in the case of either a longjmp or a thrown exception. -Additionally, this is important for implementation of 'catch' clauses -in high-level languages that support them.

    +difference is that it establishes an association with a label, which is used by the runtime library to unwind the stack.

    - +This instruction is used in languages with destructors to ensure that proper +cleanup is performed in the case of either a longjmp or a thrown +exception. Additionally, this is important for implementation of +'catch' clauses in high-level languages that support them.

    Example:
       %retval = invoke int %Test(int 15)
    -              to label %Continue except label %TestCleanup     ; {int}:retval set
    +              to label %Continue
    +              except label %TestCleanup     ; {int}:retval set
     
    @@ -1801,6 +1803,32 @@ arbitrarily complex and require memory allocation, for example.

    + +


    'llvm.unwind' Intrinsic

    @@ -1811,7 +1839,7 @@
    Chris Lattner
    -Last modified: Mon Jul 14 12:12:22 CDT 2003 +Last modified: Thu Aug 28 17:11:50 CDT 2003 From brukman at cs.uiuc.edu Thu Aug 28 17:15:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 28 17:15:01 2003 Subject: [llvm-commits] CVS: llvm/tools/bugpoint/CodeGeneratorBug.cpp ExecutionDriver.cpp Message-ID: <200308282214.RAA05403@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: CodeGeneratorBug.cpp updated: 1.17 -> 1.18 ExecutionDriver.cpp updated: 1.19 -> 1.20 --- Log message: Renaming `dis' -> `llvm-dis'. --- Diffs of the changes: Index: llvm/tools/bugpoint/CodeGeneratorBug.cpp diff -u llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.17 llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.18 --- llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.17 Sun Aug 17 18:38:53 2003 +++ llvm/tools/bugpoint/CodeGeneratorBug.cpp Thu Aug 28 17:14:16 2003 @@ -253,7 +253,7 @@ for (unsigned i=0, e = InputArgv.size(); i != e; ++i) std::cout << " " << InputArgv[i]; std::cout << "\n"; - std::cout << "The shared object was created with:\n dis -c " + std::cout << "The shared object was created with:\n llvm-dis -c " << SafeModuleBC << " -o temporary.c\n" << " gcc -xc temporary.c -O2 -o " << SharedObject #if defined(sparc) || defined(__sparc__) || defined(__sparcv9) Index: llvm/tools/bugpoint/ExecutionDriver.cpp diff -u llvm/tools/bugpoint/ExecutionDriver.cpp:1.19 llvm/tools/bugpoint/ExecutionDriver.cpp:1.20 --- llvm/tools/bugpoint/ExecutionDriver.cpp:1.19 Mon Aug 18 17:32:48 2003 +++ llvm/tools/bugpoint/ExecutionDriver.cpp Thu Aug 28 17:14:16 2003 @@ -394,7 +394,7 @@ // CBE Implementation of AbstractIntepreter interface // class CBE : public AbstractInterpreter { - std::string DISPath; // The path to the LLVM 'dis' executable + std::string DISPath; // The path to the `llvm-dis' executable GCC *gcc; public: CBE(const std::string &disPath, GCC *Gcc) : DISPath(disPath), gcc(Gcc) { } @@ -402,13 +402,14 @@ // CBE create method - Try to find the 'dis' executable static CBE *create(BugDriver *BD, std::string &Message) { - std::string DISPath = FindExecutable("dis", BD->getToolName()); + std::string DISPath = FindExecutable("llvm-dis", BD->getToolName()); if (DISPath.empty()) { - Message = "Cannot find `dis' in bugpoint executable directory or PATH!\n"; + Message = + "Cannot find `llvm-dis' in bugpoint executable directory or PATH!\n"; return 0; } - Message = "Found dis: " + DISPath + "\n"; + Message = "Found llvm-dis: " + DISPath + "\n"; GCC *gcc = GCC::create(BD, Message); if (!gcc) { @@ -445,7 +446,7 @@ if (RunProgramWithTimeout(DISPath, DisArgs, "/dev/null", "/dev/null", "/dev/null")) { // If dis failed on the bytecode, print error... - std::cerr << "bugpoint error: `dis -c' failed!\n"; + std::cerr << "bugpoint error: `llvm-dis -c' failed!\n"; return 1; } @@ -458,7 +459,7 @@ const std::string &SharedLib) { std::string OutputCFile; if (OutputC(Bytecode, OutputCFile)) { - std::cerr << "Could not generate C code with `dis', exiting.\n"; + std::cerr << "Could not generate C code with `llvm-dis', exiting.\n"; exit(1); } From lattner at cs.uiuc.edu Thu Aug 28 19:04:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 19:04:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/CompileFail/2003-08-28-SaveExprBug.cpp Message-ID: <200308290003.TAA11719@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend/CompileFail: 2003-08-28-SaveExprBug.cpp added (r1.1) --- Log message: New testcase, not only possible of causing compilation failures, but could also cause miscompilations! --- Diffs of the changes: Index: llvm/test/Regression/C++Frontend/CompileFail/2003-08-28-SaveExprBug.cpp diff -c /dev/null llvm/test/Regression/C++Frontend/CompileFail/2003-08-28-SaveExprBug.cpp:1.1 *** /dev/null Thu Aug 28 19:03:55 2003 --- llvm/test/Regression/C++Frontend/CompileFail/2003-08-28-SaveExprBug.cpp Thu Aug 28 19:03:45 2003 *************** *** 0 **** --- 1,22 ---- + + char* eback(); + + template + struct basic_filebuf { + char *instancevar; + + void callee() { + instancevar += eback() != eback(); + } + + void caller(); + }; + + + template + void basic_filebuf<_CharT>::caller() { + callee(); + } + + + template class basic_filebuf; From lattner at cs.uiuc.edu Thu Aug 28 19:31:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 19:31:03 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/CompileFail/2003-08-28-ForwardType.cpp Message-ID: <200308290030.TAA13153@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend/CompileFail: 2003-08-28-ForwardType.cpp added (r1.1) --- Log message: NEw testcase --- Diffs of the changes: Index: llvm/test/Regression/C++Frontend/CompileFail/2003-08-28-ForwardType.cpp diff -c /dev/null llvm/test/Regression/C++Frontend/CompileFail/2003-08-28-ForwardType.cpp:1.1 *** /dev/null Thu Aug 28 19:30:05 2003 --- llvm/test/Regression/C++Frontend/CompileFail/2003-08-28-ForwardType.cpp Thu Aug 28 19:29:55 2003 *************** *** 0 **** --- 1,20 ---- + + // Default placement versions of operator new. + inline void* operator new(unsigned, void* __p) throw(); + + + template + struct stdio_filebuf + { stdio_filebuf(); + + }; + + extern stdio_filebuf buf_cout; + + void foo() { + // Create stream buffers for the standard streams and use + // those buffers without destroying and recreating the + // streams. + new (&buf_cout) stdio_filebuf(); + + } From brukman at cs.uiuc.edu Thu Aug 28 23:24:00 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Aug 28 23:24:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp Message-ID: <200308290423.XAA05491@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: SparcV9CodeEmitter.cpp updated: 1.30 -> 1.31 --- Log message: * Use alloca() to force GCC not to eliminate frame pointer * Break apart saving and restoring registers into separate functions * Instead of saving single and double FP registers, just save the double registers -- aliasing helps preserve the single FP registers as well. * Request just as much memory for a stub as we actually use --- Diffs of the changes: Index: llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp diff -u llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.30 llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.31 --- llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.30 Fri Aug 15 13:03:06 2003 +++ llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp Thu Aug 28 23:22:54 2003 @@ -19,6 +19,7 @@ #include "Support/hash_set" #include "SparcInternals.h" #include "SparcV9CodeEmitter.h" +#include "Config/alloca.h" bool UltraSparc::addPassesToEmitMachineCode(FunctionPassManager &PM, MachineCodeEmitter &MCE) { @@ -75,8 +76,9 @@ private: uint64_t emitStubForFunction(Function *F); - static void SaveRestoreRegisters(); - static uint64_t CompilationCallback(); + static void SaveRegisters(uint64_t DoubleFP[]); + static void RestoreRegisters(uint64_t DoubleFP[]); + static void CompilationCallback(); uint64_t resolveFunctionReference(uint64_t RetAddr); }; @@ -92,7 +94,7 @@ /// uint64_t JITResolver::addFunctionReference(uint64_t Address, Function *F) { LazyCodeGenMap[Address] = F; - return (intptr_t)&JITResolver::SaveRestoreRegisters; + return (intptr_t)&JITResolver::CompilationCallback; } /// deleteFunctionReference - If we are emitting a far call, we already added a @@ -162,61 +164,37 @@ return Addr; } -void JITResolver::SaveRestoreRegisters() { - uint32_t SingleFP[32]; - uint64_t DoubleFP[16]; - // FIXME: uint128_t QuadFloatRegs[..]; - uint64_t CCR, FSR, FPRS, g1, g5; - +void JITResolver::SaveRegisters(uint64_t DoubleFP[]) { #if defined(sparc) || defined(__sparc__) || defined(__sparcv9) - __asm__ __volatile__ (// Save g1 and g5 - "stx %%g1, %0;\n\t" "stx %%g5, %1;\n\t" - : "=m"(g1), "=m"(g5)); +#if 0 __asm__ __volatile__ (// Save condition-code registers "stx %%fsr, %0;\n\t" "rd %%fprs, %1;\n\t" "rd %%ccr, %2;\n\t" : "=m"(FSR), "=r"(FPRS), "=r"(CCR)); +#endif // GCC says: `asm' only allows up to thirty parameters! - __asm__ __volatile__ (// Save Single FP registers, part 1 - "st %%f0, %0;\n\t" "st %%f1, %1;\n\t" - "st %%f2, %2;\n\t" "st %%f3, %3;\n\t" - "st %%f4, %4;\n\t" "st %%f5, %5;\n\t" - "st %%f6, %6;\n\t" "st %%f7, %7;\n\t" - "st %%f8, %8;\n\t" "st %%f9, %9;\n\t" - "st %%f10, %10;\n\t" "st %%f11, %11;\n\t" - "st %%f12, %12;\n\t" "st %%f13, %13;\n\t" - "st %%f14, %14;\n\t" "st %%f15, %15;\n\t" - : "=m"(SingleFP[ 0]), "=m"(SingleFP[ 1]), - "=m"(SingleFP[ 2]), "=m"(SingleFP[ 3]), - "=m"(SingleFP[ 4]), "=m"(SingleFP[ 5]), - "=m"(SingleFP[ 6]), "=m"(SingleFP[ 7]), - "=m"(SingleFP[ 8]), "=m"(SingleFP[ 9]), - "=m"(SingleFP[10]), "=m"(SingleFP[11]), - "=m"(SingleFP[12]), "=m"(SingleFP[13]), - "=m"(SingleFP[14]), "=m"(SingleFP[15])); + __asm__ __volatile__ (// Save Single/Double FP registers, part 1 + "std %%f0, %0;\n\t" "std %%f2, %1;\n\t" + "std %%f4, %2;\n\t" "std %%f6, %3;\n\t" + "std %%f8, %4;\n\t" "std %%f10, %5;\n\t" + "std %%f12, %6;\n\t" "std %%f14, %7;\n\t" + "std %%f16, %8;\n\t" "std %%f18, %9;\n\t" + "std %%f20, %10;\n\t" "std %%f22, %11;\n\t" + "std %%f24, %12;\n\t" "std %%f26, %13;\n\t" + "std %%f28, %14;\n\t" "std %%f30, %15;\n\t" + : "=m"(DoubleFP[ 0]), "=m"(DoubleFP[ 1]), + "=m"(DoubleFP[ 2]), "=m"(DoubleFP[ 3]), + "=m"(DoubleFP[ 4]), "=m"(DoubleFP[ 5]), + "=m"(DoubleFP[ 6]), "=m"(DoubleFP[ 7]), + "=m"(DoubleFP[ 8]), "=m"(DoubleFP[ 9]), + "=m"(DoubleFP[10]), "=m"(DoubleFP[11]), + "=m"(DoubleFP[12]), "=m"(DoubleFP[13]), + "=m"(DoubleFP[14]), "=m"(DoubleFP[15])); - __asm__ __volatile__ (// Save Single FP registers, part 2 - "st %%f16, %0;\n\t" "st %%f17, %1;\n\t" - "st %%f18, %2;\n\t" "st %%f19, %3;\n\t" - "st %%f20, %4;\n\t" "st %%f21, %5;\n\t" - "st %%f22, %6;\n\t" "st %%f23, %7;\n\t" - "st %%f24, %8;\n\t" "st %%f25, %9;\n\t" - "st %%f26, %10;\n\t" "st %%f27, %11;\n\t" - "st %%f28, %12;\n\t" "st %%f29, %13;\n\t" - "st %%f30, %14;\n\t" "st %%f31, %15;\n\t" - : "=m"(SingleFP[16]), "=m"(SingleFP[17]), - "=m"(SingleFP[18]), "=m"(SingleFP[19]), - "=m"(SingleFP[20]), "=m"(SingleFP[21]), - "=m"(SingleFP[22]), "=m"(SingleFP[23]), - "=m"(SingleFP[24]), "=m"(SingleFP[25]), - "=m"(SingleFP[26]), "=m"(SingleFP[27]), - "=m"(SingleFP[28]), "=m"(SingleFP[29]), - "=m"(SingleFP[30]), "=m"(SingleFP[31])); - - __asm__ __volatile__ (// Save Double FP registers + __asm__ __volatile__ (// Save Double FP registers, part 2 "std %%f32, %0;\n\t" "std %%f34, %1;\n\t" "std %%f36, %2;\n\t" "std %%f38, %3;\n\t" "std %%f40, %4;\n\t" "std %%f42, %5;\n\t" @@ -225,71 +203,49 @@ "std %%f52, %10;\n\t" "std %%f54, %11;\n\t" "std %%f56, %12;\n\t" "std %%f58, %13;\n\t" "std %%f60, %14;\n\t" "std %%f62, %15;\n\t" - : "=m"(DoubleFP[32/2-16]), "=m"(DoubleFP[34/2-16]), - "=m"(DoubleFP[36/2-16]), "=m"(DoubleFP[38/2-16]), - "=m"(DoubleFP[40/2-16]), "=m"(DoubleFP[42/2-16]), - "=m"(DoubleFP[44/2-16]), "=m"(DoubleFP[46/2-16]), - "=m"(DoubleFP[48/2-16]), "=m"(DoubleFP[50/2-16]), - "=m"(DoubleFP[52/2-16]), "=m"(DoubleFP[54/2-16]), - "=m"(DoubleFP[56/2-16]), "=m"(DoubleFP[58/2-16]), - "=m"(DoubleFP[60/2-16]), "=m"(DoubleFP[62/2-16])); + : "=m"(DoubleFP[16]), "=m"(DoubleFP[17]), + "=m"(DoubleFP[18]), "=m"(DoubleFP[19]), + "=m"(DoubleFP[20]), "=m"(DoubleFP[21]), + "=m"(DoubleFP[22]), "=m"(DoubleFP[23]), + "=m"(DoubleFP[24]), "=m"(DoubleFP[25]), + "=m"(DoubleFP[26]), "=m"(DoubleFP[27]), + "=m"(DoubleFP[28]), "=m"(DoubleFP[29]), + "=m"(DoubleFP[30]), "=m"(DoubleFP[31])); #endif +} - // Resolve the function call - register uint64_t restoreAddr = CompilationCallback(); +void JITResolver::RestoreRegisters(uint64_t DoubleFP[]) { #if defined(sparc) || defined(__sparc__) || defined(__sparcv9) - // Set the return address to re-execute the `restore' instruction - __asm__ __volatile__ ("or %%o0, %%g0, %%i7;\n\t" - - // Restore g1 and g5 - "ldx %0, %%g1;\n\t" "ldx %1, %%g5;\n\t" - :: "m"(g1), "m"(g5)); +#if 0 __asm__ __volatile__ (// Restore condition-code registers "ldx %0, %%fsr;\n\t" "wr %1, 0, %%fprs;\n\t" "wr %2, 0, %%ccr;\n\t" :: "m"(FSR), "r"(FPRS), "r"(CCR)); +#endif // GCC says: `asm' only allows up to thirty parameters! - __asm__ __volatile__ (// Restore Single FP registers, part 1 - "ld %0, %%f0;\n\t" "ld %1, %%f1;\n\t" - "ld %2, %%f2;\n\t" "ld %3, %%f3;\n\t" - "ld %4, %%f4;\n\t" "ld %5, %%f5;\n\t" - "ld %6, %%f6;\n\t" "ld %7, %%f7;\n\t" - "ld %8, %%f8;\n\t" "ld %9, %%f9;\n\t" - "ld %10, %%f10;\n\t" "ld %11, %%f11;\n\t" - "ld %12, %%f12;\n\t" "ld %13, %%f13;\n\t" - "ld %14, %%f14;\n\t" "ld %15, %%f15;\n\t" - :: "m"(SingleFP[0]), "m"(SingleFP[1]), - "m"(SingleFP[2]), "m"(SingleFP[3]), - "m"(SingleFP[4]), "m"(SingleFP[5]), - "m"(SingleFP[6]), "m"(SingleFP[7]), - "m"(SingleFP[8]), "m"(SingleFP[9]), - "m"(SingleFP[10]), "m"(SingleFP[11]), - "m"(SingleFP[12]), "m"(SingleFP[13]), - "m"(SingleFP[14]), "m"(SingleFP[15])); - - __asm__ __volatile__ (// Restore Single FP registers, part 2 - "ld %0, %%f16;\n\t" "ld %1, %%f17;\n\t" - "ld %2, %%f18;\n\t" "ld %3, %%f19;\n\t" - "ld %4, %%f20;\n\t" "ld %5, %%f21;\n\t" - "ld %6, %%f22;\n\t" "ld %7, %%f23;\n\t" - "ld %8, %%f24;\n\t" "ld %9, %%f25;\n\t" - "ld %10, %%f26;\n\t" "ld %11, %%f27;\n\t" - "ld %12, %%f28;\n\t" "ld %13, %%f29;\n\t" - "ld %14, %%f30;\n\t" "ld %15, %%f31;\n\t" - :: "m"(SingleFP[16]), "m"(SingleFP[17]), - "m"(SingleFP[18]), "m"(SingleFP[19]), - "m"(SingleFP[20]), "m"(SingleFP[21]), - "m"(SingleFP[22]), "m"(SingleFP[23]), - "m"(SingleFP[24]), "m"(SingleFP[25]), - "m"(SingleFP[26]), "m"(SingleFP[27]), - "m"(SingleFP[28]), "m"(SingleFP[29]), - "m"(SingleFP[30]), "m"(SingleFP[31])); + __asm__ __volatile__ (// Restore Single/Double FP registers, part 1 + "ldd %0, %%f0;\n\t" "ldd %1, %%f2;\n\t" + "ldd %2, %%f4;\n\t" "ldd %3, %%f6;\n\t" + "ldd %4, %%f8;\n\t" "ldd %5, %%f10;\n\t" + "ldd %6, %%f12;\n\t" "ldd %7, %%f14;\n\t" + "ldd %8, %%f16;\n\t" "ldd %9, %%f18;\n\t" + "ldd %10, %%f20;\n\t" "ldd %11, %%f22;\n\t" + "ldd %12, %%f24;\n\t" "ldd %13, %%f26;\n\t" + "ldd %14, %%f28;\n\t" "ldd %15, %%f30;\n\t" + :: "m"(DoubleFP[0]), "m"(DoubleFP[1]), + "m"(DoubleFP[2]), "m"(DoubleFP[3]), + "m"(DoubleFP[4]), "m"(DoubleFP[5]), + "m"(DoubleFP[6]), "m"(DoubleFP[7]), + "m"(DoubleFP[8]), "m"(DoubleFP[9]), + "m"(DoubleFP[10]), "m"(DoubleFP[11]), + "m"(DoubleFP[12]), "m"(DoubleFP[13]), + "m"(DoubleFP[14]), "m"(DoubleFP[15])); - __asm__ __volatile__ (// Restore Double FP registers + __asm__ __volatile__ (// Restore Double FP registers, part 2 "ldd %0, %%f32;\n\t" "ldd %1, %%f34;\n\t" "ldd %2, %%f36;\n\t" "ldd %3, %%f38;\n\t" "ldd %4, %%f40;\n\t" "ldd %5, %%f42;\n\t" @@ -298,19 +254,25 @@ "ldd %10, %%f52;\n\t" "ldd %11, %%f54;\n\t" "ldd %12, %%f56;\n\t" "ldd %13, %%f58;\n\t" "ldd %14, %%f60;\n\t" "ldd %15, %%f62;\n\t" - :: "m"(DoubleFP[32/2-16]), "m"(DoubleFP[34/2-16]), - "m"(DoubleFP[36/2-16]), "m"(DoubleFP[38/2-16]), - "m"(DoubleFP[40/2-16]), "m"(DoubleFP[42/2-16]), - "m"(DoubleFP[44/2-16]), "m"(DoubleFP[46/2-16]), - "m"(DoubleFP[48/2-16]), "m"(DoubleFP[50/2-16]), - "m"(DoubleFP[52/2-16]), "m"(DoubleFP[54/2-16]), - "m"(DoubleFP[56/2-16]), "m"(DoubleFP[58/2-16]), - "m"(DoubleFP[60/2-16]), "m"(DoubleFP[62/2-16])); + :: "m"(DoubleFP[16]), "m"(DoubleFP[17]), + "m"(DoubleFP[18]), "m"(DoubleFP[19]), + "m"(DoubleFP[20]), "m"(DoubleFP[21]), + "m"(DoubleFP[22]), "m"(DoubleFP[23]), + "m"(DoubleFP[24]), "m"(DoubleFP[25]), + "m"(DoubleFP[26]), "m"(DoubleFP[27]), + "m"(DoubleFP[28]), "m"(DoubleFP[29]), + "m"(DoubleFP[30]), "m"(DoubleFP[31])); #endif } -uint64_t JITResolver::CompilationCallback() { - uint64_t CameFrom = (uint64_t)(intptr_t)__builtin_return_address(1); +void JITResolver::CompilationCallback() { + // Local space to save double registers + uint64_t DoubleFP[32]; + //uint64_t CCR, FSR, FPRS; + + SaveRegisters(DoubleFP); + + uint64_t CameFrom = (uint64_t)(intptr_t)__builtin_return_address(0); int64_t Target = (int64_t)TheJITResolver->resolveFunctionReference(CameFrom); DEBUG(std::cerr << "In callback! Addr=0x" << std::hex << CameFrom << "\n"); register int64_t returnAddr = 0; @@ -331,13 +293,23 @@ // farCall (7 instructions) uint64_t Offset = (LazyCallFlavor[CameFrom] == ShortCall) ? 4 : 28; uint64_t CodeBegin = CameFrom - Offset; + + // FIXME FIXME FIXME FIXME: __builtin_frame_address doesn't work if frame + // pointer elimination has been performed. Having a variable sized alloca + // disables frame pointer elimination currently, even if it's dead. This is a + // gross hack. + alloca(42+Offset); + // FIXME FIXME FIXME FIXME // Make sure that what we're about to overwrite is indeed "save" MachineInstr *SV = BuildMI(V9::SAVEi, 3).addReg(o6).addSImm(-192).addReg(o6); unsigned SaveInst = TheJITResolver->getBinaryCodeForInstr(*SV); delete SV; unsigned CodeInMem = *(unsigned*)(intptr_t)CodeBegin; - assert(CodeInMem == SaveInst && "About to overwrite smthg not a save instr!"); + if (CodeInMem != SaveInst) { + std::cerr << "About to overwrite smthg not a save instr!"; + abort(); + } DEBUG(std::cerr << "Emitting a far jump to 0x" << std::hex << Target << "\n"); TheJITResolver->insertFarJumpAtAddr(Target, CodeBegin); @@ -357,13 +329,17 @@ delete MI; #endif + RestoreRegisters(DoubleFP); + // Change the return address to reexecute the restore, then the jump However, // we can't just modify %i7 here, because we return to the function that will // restore the floating-point registers for us. Thus, we just return the value // we want it to be, and the parent will take care of setting %i7 correctly. DEBUG(std::cerr << "Callback returning the addr of restore inst: " << std::hex << (CameFrom-Offset-12) << "\n"); - return CameFrom - Offset - 12; // 8 because of call+delay, 4 more to restore +#if defined(sparc) || defined(__sparc__) || defined(__sparcv9) + __asm__ __volatile__ ("sub %%i7, %0, %%i7" : : "r" (Offset+12)); +#endif } /// emitStubForFunction - This method is used by the JIT when it needs to emit @@ -373,8 +349,7 @@ /// directly. /// uint64_t JITResolver::emitStubForFunction(Function *F) { - // FIXME: 40 is not enough... but should be - MCE.startFunctionStub(*F, 64); + MCE.startFunctionStub(*F, 44); DEBUG(std::cerr << "Emitting stub at addr: 0x" << std::hex << MCE.getCurrentPCValue() << "\n"); From lattner at cs.uiuc.edu Thu Aug 28 23:41:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 23:41:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Linker/2003-08-28-TypeResolvesGlobal.ll Message-ID: <200308290440.XAA21519@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Linker: 2003-08-28-TypeResolvesGlobal.ll added (r1.1) --- Log message: New testcase which is preventing the linking of libstdc++ --- Diffs of the changes: Index: llvm/test/Regression/Linker/2003-08-28-TypeResolvesGlobal.ll diff -c /dev/null llvm/test/Regression/Linker/2003-08-28-TypeResolvesGlobal.ll:1.1 *** /dev/null Thu Aug 28 23:40:44 2003 --- llvm/test/Regression/Linker/2003-08-28-TypeResolvesGlobal.ll Thu Aug 28 23:40:34 2003 *************** *** 0 **** --- 1,12 ---- + ; RUN: as < %s > Output/%s.out1.bc + ; RUN: echo "%S = type int" | as > Output/%s.out2.bc + ; RUN: link Output/%s.out[21].bc + + %S = type opaque + + void %foo(int* %V) { + ret void + } + + declare void %foo(%S*) + From lattner at cs.uiuc.edu Thu Aug 28 23:51:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 23:51:01 2003 Subject: [llvm-commits] CVS: llvm/lib/VMCore/SymbolTable.cpp Message-ID: <200308290450.XAA22078@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: SymbolTable.cpp updated: 1.30 -> 1.31 --- Log message: Fix bug: Linker/2003-08-28-TypeResolvesGlobal.ll --- Diffs of the changes: Index: llvm/lib/VMCore/SymbolTable.cpp diff -u llvm/lib/VMCore/SymbolTable.cpp:1.30 llvm/lib/VMCore/SymbolTable.cpp:1.31 --- llvm/lib/VMCore/SymbolTable.cpp:1.30 Wed Jul 23 10:30:06 2003 +++ llvm/lib/VMCore/SymbolTable.cpp Thu Aug 28 23:49:54 2003 @@ -231,11 +231,21 @@ GlobalValue *ExistGV = dyn_cast(TI->second); GlobalValue *NewGV = dyn_cast(V.second); - if (ExistGV && NewGV && ExistGV->isExternal() && NewGV->isExternal()) { + if (ExistGV && NewGV) { + assert((ExistGV->isExternal() || NewGV->isExternal()) && + "Two planes folded together with overlapping value names!"); + + // Make sure that ExistGV is the one we want to keep! + if (!NewGV->isExternal() || !NewGV->use_empty()) { + std::swap(NewGV, ExistGV); + } + // Ok we have two external global values. Make all uses of the new // one use the old one... // - assert(ExistGV->use_empty() && "No uses allowed on untyped value!"); + assert(NewGV->use_empty() && "No uses allowed on untyped value!"); + + // We cannot replaceAllUsesWith, because they have different types! //NewGV->replaceAllUsesWith(ExistGV); // Now we just convert it to an unnamed method... which won't get @@ -261,10 +271,6 @@ else M->getGlobalList().remove(cast(NewGV)); delete NewGV; - - } else { - assert(0 && "Two planes folded together with overlapping " - "value names!"); } } else { insertEntry(V.first, NewType, V.second); From lattner at cs.uiuc.edu Thu Aug 28 23:55:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Aug 28 23:55:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Linker/2003-08-28-TypeResolvesGlobal2.ll Message-ID: <200308290454.XAA22347@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Linker: 2003-08-28-TypeResolvesGlobal2.ll added (r1.1) --- Log message: Ok, the last bug fix was not good enough to fix libstdc++. Maybe this one will be --- Diffs of the changes: Index: llvm/test/Regression/Linker/2003-08-28-TypeResolvesGlobal2.ll diff -c /dev/null llvm/test/Regression/Linker/2003-08-28-TypeResolvesGlobal2.ll:1.1 *** /dev/null Thu Aug 28 23:54:33 2003 --- llvm/test/Regression/Linker/2003-08-28-TypeResolvesGlobal2.ll Thu Aug 28 23:54:23 2003 *************** *** 0 **** --- 1,17 ---- + ; RUN: as < %s > Output/%s.out1.bc + ; RUN: echo "%S = type int" | as > Output/%s.out2.bc + ; RUN: link Output/%s.out[21].bc + + %S = type opaque + + void %foo(int* %V) { + ret void + } + + declare void %foo(%S*) + + void %other() { + call void %foo(%S* null) ; Add a use of the unresolved proto + call void %foo(int* null) ; Add a use of the resolved function + ret void + } From lattner at cs.uiuc.edu Fri Aug 29 00:09:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 29 00:09:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Value.h Message-ID: <200308290508.AAA12911@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Value.h updated: 1.41 -> 1.42 --- Log message: Add new method --- Diffs of the changes: Index: llvm/include/llvm/Value.h diff -u llvm/include/llvm/Value.h:1.41 llvm/include/llvm/Value.h:1.42 --- llvm/include/llvm/Value.h:1.41 Wed Jun 18 14:22:36 2003 +++ llvm/include/llvm/Value.h Fri Aug 29 00:08:31 2003 @@ -89,6 +89,10 @@ /// void replaceAllUsesWith(Value *V); + // uncheckedReplaceAllUsesWith - Just like replaceAllUsesWith but dangerous. + // Only use when in type resolution situations! + void uncheckedReplaceAllUsesWith(Value *V); + /// refineAbstractType - This function is implemented because we use /// potentially abstract types, and these types may be resolved to more /// concrete types after we are constructed. From lattner at cs.uiuc.edu Fri Aug 29 00:10:06 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 29 00:10:06 2003 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Value.cpp Message-ID: <200308290509.AAA12926@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.50 -> 1.51 Value.cpp updated: 1.32 -> 1.33 --- Log message: Refactor code to make it useful outside of Constants.cpp --- Diffs of the changes: Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.50 llvm/lib/VMCore/Constants.cpp:1.51 --- llvm/lib/VMCore/Constants.cpp:1.50 Thu Aug 21 17:12:47 2003 +++ llvm/lib/VMCore/Constants.cpp Fri Aug 29 00:09:37 2003 @@ -466,26 +466,6 @@ //===----------------------------------------------------------------------===// // Factory Function Implementation -// ReplaceUsesOfWith - This is exactly the same as Value::replaceAllUsesWith, -// except that it doesn't have all of the asserts. The asserts fail because we -// are half-way done resolving types, which causes some types to exist as two -// different Type*'s at the same time. This is a sledgehammer to work around -// this problem. -// -static void ReplaceUsesOfWith(Value *Old, Value *New) { - while (!Old->use_empty()) { - User *Use = Old->use_back(); - // Must handle Constants specially, we cannot call replaceUsesOfWith on a - // constant! - if (Constant *C = dyn_cast(Use)) { - C->replaceUsesOfWithOnConstant(Old, New); - } else { - Use->replaceUsesOfWith(Old, New); - } - } -} - - // ConstantCreator - A class that is used to create constants by // ValueMap*. This class should be partially specialized if there is // something strange that needs to be done to interface to the ctor for the @@ -596,7 +576,7 @@ C.push_back(cast(getOperand(i))); Constant *New = ConstantArray::get(cast(NewTy), C); if (New != this) { - ReplaceUsesOfWith(this, New); + uncheckedReplaceAllUsesWith(New); destroyConstant(); // This constant is now dead, destroy it. } } @@ -665,7 +645,7 @@ C.push_back(cast(getOperand(i))); Constant *New = ConstantStruct::get(cast(NewTy), C); if (New != this) { - ReplaceUsesOfWith(this, New); + uncheckedReplaceAllUsesWith(New); destroyConstant(); // This constant is now dead, destroy it. } } @@ -706,7 +686,7 @@ // Make everyone now use a constant of the new type... Constant *New = ConstantPointerNull::get(cast(NewTy)); if (New != this) { - ReplaceUsesOfWith(this, New); + uncheckedReplaceAllUsesWith(New); // This constant is now dead, destroy it. destroyConstant(); @@ -859,7 +839,7 @@ New = ConstantExpr::getGetElementPtr(getOperand(0), C); } if (New != this) { - ReplaceUsesOfWith(this, New); + uncheckedReplaceAllUsesWith(New); destroyConstant(); // This constant is now dead, destroy it. } } Index: llvm/lib/VMCore/Value.cpp diff -u llvm/lib/VMCore/Value.cpp:1.32 llvm/lib/VMCore/Value.cpp:1.33 --- llvm/lib/VMCore/Value.cpp:1.32 Tue Jun 24 17:20:19 2003 +++ llvm/lib/VMCore/Value.cpp Fri Aug 29 00:09:37 2003 @@ -66,6 +66,26 @@ } } +// uncheckedReplaceAllUsesWith - This is exactly the same as replaceAllUsesWith, +// except that it doesn't have all of the asserts. The asserts fail because we +// are half-way done resolving types, which causes some types to exist as two +// different Type*'s at the same time. This is a sledgehammer to work around +// this problem. +// +void Value::uncheckedReplaceAllUsesWith(Value *New) { + while (!Uses.empty()) { + User *Use = Uses.back(); + // Must handle Constants specially, we cannot call replaceUsesOfWith on a + // constant! + if (Constant *C = dyn_cast(Use)) { + C->replaceUsesOfWithOnConstant(this, New); + } else { + Use->replaceUsesOfWith(this, New); + } + } +} + + // refineAbstractType - This function is implemented because we use // potentially abstract types, and these types may be resolved to more // concrete types after we are constructed. For the value class, we simply From lattner at cs.uiuc.edu Fri Aug 29 00:12:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 29 00:12:01 2003 Subject: [llvm-commits] CVS: llvm/lib/VMCore/SymbolTable.cpp Message-ID: <200308290511.AAA12941@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: SymbolTable.cpp updated: 1.31 -> 1.32 --- Log message: Fix bug: Linker/2003-08-28-TypeResolvesGlobal2.ll --- Diffs of the changes: Index: llvm/lib/VMCore/SymbolTable.cpp diff -u llvm/lib/VMCore/SymbolTable.cpp:1.31 llvm/lib/VMCore/SymbolTable.cpp:1.32 --- llvm/lib/VMCore/SymbolTable.cpp:1.31 Thu Aug 28 23:49:54 2003 +++ llvm/lib/VMCore/SymbolTable.cpp Fri Aug 29 00:11:34 2003 @@ -236,17 +236,12 @@ "Two planes folded together with overlapping value names!"); // Make sure that ExistGV is the one we want to keep! - if (!NewGV->isExternal() || !NewGV->use_empty()) { + if (!NewGV->isExternal()) std::swap(NewGV, ExistGV); - } // Ok we have two external global values. Make all uses of the new // one use the old one... - // - assert(NewGV->use_empty() && "No uses allowed on untyped value!"); - - // We cannot replaceAllUsesWith, because they have different types! - //NewGV->replaceAllUsesWith(ExistGV); + NewGV->uncheckedReplaceAllUsesWith(ExistGV); // Now we just convert it to an unnamed method... which won't get // added to our symbol table. The problem is that if we call From gaeke at cs.uiuc.edu Fri Aug 29 00:14:01 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Aug 29 00:14:01 2003 Subject: [llvm-commits] CVS: reopt/lib/Mapping/getLLVMinfo.cpp Message-ID: <200308290513.AAA00952@trinity.cs.uiuc.edu> Changes in directory reopt/lib/Mapping: getLLVMinfo.cpp updated: 1.18 -> 1.19 --- Log message: Don't fail an assert if we see a module with a function which isn't in the llvmSimpleFunction table; just be safe and return false. --- Diffs of the changes: Index: reopt/lib/Mapping/getLLVMinfo.cpp diff -u reopt/lib/Mapping/getLLVMinfo.cpp:1.18 reopt/lib/Mapping/getLLVMinfo.cpp:1.19 --- reopt/lib/Mapping/getLLVMinfo.cpp:1.18 Fri Aug 22 12:43:41 2003 +++ reopt/lib/Mapping/getLLVMinfo.cpp Fri Aug 29 00:12:48 2003 @@ -232,8 +232,15 @@ int i = 0; for (Module::iterator FI = M->begin (), FE = M->end (); FE != FI; ++FI) { if (FI->isExternal ()) continue; - assert (i < llvmFunctionCount && "No such function in function table"); - FunctionInlinable[FI] = llvmSimpleFunction[i]; + if (i >= llvmFunctionCount) { + // This is a function that must not have been seen by the + // -emitfuncs pass, assuming that the functions in M haven't + // been reordered since -emitfuncs saw them. Assume it's not + // inlinable (instead of failing an assert as before.) + FunctionInlinable[FI] = false; + } else { + FunctionInlinable[FI] = llvmSimpleFunction[i]; + } ++i; } lastUsedModule = M; From gaeke at cs.uiuc.edu Fri Aug 29 00:14:07 2003 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Aug 29 00:14:07 2003 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/TraceToFunction.cpp Message-ID: <200308290513.AAA00945@trinity.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: TraceToFunction.cpp updated: 1.1 -> 1.2 --- Log message: Move phi/call instruction cleanups to a separate function, and do them all afterwards in a separate pass. Also, move deletion of instructions out into a separate for loop to avoid invalidating the BasicBlock iterators. Don't fail an assertion if the Phi node has 0 uses, because it will be deleted anyway. (These three fixes seem to fix qbsort.) Add more assertions. --- Diffs of the changes: Index: reopt/lib/LightWtProfiling/TraceToFunction.cpp diff -u reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.1 reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.2 --- reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.1 Thu Aug 28 12:39:03 2003 +++ reopt/lib/LightWtProfiling/TraceToFunction.cpp Fri Aug 29 00:13:12 2003 @@ -209,6 +209,89 @@ } } +static void fixupPhisAndCalls (BasicBlock *dstB) { + std::vector goners; + Function *F = dstB->getParent (); + // Fix up Phi nodes: + for (BasicBlock::iterator BI = dstB->begin (), BE = dstB->end (); + BI != BE; ++BI) { + Instruction &I = *BI; + // In all cases, if a Phi node source in T was an on-trace basic + // block, then it will already have been fixed up to point to + // that block's clone, so we find off-trace sources by looking + // for source BBs which are not in F. + if (PHINode *PN = dyn_cast (&I)) { + unsigned onTraceSources = 0; + int lastSrcFound = -1; + for (unsigned i = 0; i < PN->getNumIncomingValues (); ++i) + if (PN->getIncomingBlock (i)->getParent () == F) { + lastSrcFound = i; + ++onTraceSources; + } + // Case 0. If it has 0 sources on the trace, that should really + // never happen. + assert (onTraceSources != 0 + && "Phi node on trace has ALL its sources from off-trace!"); + // Case 1. If it has 1 source S on the trace, replace its uses + // with S. + if (onTraceSources == 1) { + DEBUG(std::cerr << "Replacing Phi node" << *PN + << " with its lone on-trace input " + << *PN->getIncomingValue (lastSrcFound) << "\n"); + PN->replaceAllUsesWith (PN->getIncomingValue (lastSrcFound)); + goners.push_back (BI); // Delete non-used phi node later. + } else { + // Case N. If it has >1 source on the trace, just delete + // sources from the Phi node that are not on the trace. + int lastOffTraceSrcFound; + do { + lastOffTraceSrcFound = -1; + for (unsigned i = 0; i < PN->getNumIncomingValues (); ++i) + if (PN->getIncomingBlock (i)->getParent () != F) { + lastOffTraceSrcFound = i; // Found an off-trace source. + break; + } + if (lastOffTraceSrcFound != -1) { // Found one? + DEBUG(std::cerr << "Removing off-trace input " + << *PN->getIncomingValue (lastOffTraceSrcFound) + << " from Phi node " << *PN << "\n"); + PN->removeIncomingValue (lastOffTraceSrcFound); // Delete it. + } + } while (lastOffTraceSrcFound != -1); // Continue until none found. + } + } + // Make sure that our Phi fixups did the Right Thing. + DEBUG(if (PHINode *PN = dyn_cast (&I)) + if (PN->use_size () != 0) // 0-use nodes get deleted later + for (unsigned i = 0; i < PN->getNumIncomingValues (); ++i) + assert (PN->getIncomingBlock (i)->getParent () == F && + "Sorry, fixupPhisAndCalls mishandled a Phi node")); + } + + // Remove calls to first-level instrumentation if we find them. + for (BasicBlock::iterator BI = dstB->begin (), BE = dstB->end (); + BI != BE; ++BI) { + Instruction &I = *BI; + if (CallInst *CI = dyn_cast (&I)) { + Function *CF = CI->getCalledFunction (); + + if (CF && CF->isExternal () && CF->hasName() + && CF->getName () == "llvm_first_trigger") { + DEBUG(std::cerr << " (Found a call instruction " << *CI + << " ... Smells like llvm_first_trigger.)\n"); + goners.push_back (BI); + } + } + } + + while (!goners.empty ()) { + assert (goners.back ()->use_size () == 0 + && "Whoops, I was going to delete something which still has uses"); + dstB->getInstList ().erase (goners.back ()); + goners.pop_back (); + } +} + /// fillInFunctionBody - Clone the BBs of T into F, then do all /// necessary fixups to ensure that F's new contents are internally /// consistent and that the live-outs So get stored in F's first @@ -231,6 +314,8 @@ assert (dstB && "Clone of basic block I just cloned is not a basic block"); fixupFunctionBodyBB (T, F, srcB, dstB, O2CMap, So); } + for (Function::iterator FI = F->begin (), FE = F->end (); FI != FE; ++FI) + fixupPhisAndCalls (FI); } /// fixupFunctionBodyBB - Given srcB in T and its clone dstB in F, and @@ -243,6 +328,9 @@ BasicBlock *srcB, BasicBlock *dstB, ValueMap &O2CMap, LiveVariableSet &So) { + assert (T.contains (srcB) && "Source BB is not on the trace"); + assert (dstB->getParent () == F && "Clone is not in the function"); + // Additional special handling for trace's entry basic block: // The old entry BB's clone will start with a phi, one of whose args // comes from off-trace (that's the trace entry point.) We can't @@ -383,74 +471,6 @@ "no one told me today was opposite day!"); } }); - } - - // Fix up Phi nodes: - for (BasicBlock::iterator BI = dstB->begin (), BE = dstB->end (); - BI != BE; ++BI) { - Instruction &I = *BI; - // In all cases, if a Phi node source in T was an on-trace basic - // block, then it will already have been fixed up to point to - // that block's clone, so we find off-trace sources by looking - // for source BBs which are not in F. - if (PHINode *PN = dyn_cast (&I)) { - unsigned onTraceSources = 0; - int lastSrcFound = -1; - for (unsigned i = 0; i < PN->getNumIncomingValues (); ++i) - if (PN->getIncomingBlock (i)->getParent () == F) { - lastSrcFound = i; - ++onTraceSources; - } - // Case 0. If it has 0 sources on the trace, that should really - // never happen. - assert (onTraceSources != 0 - && "Phi node on trace has ALL its sources from off-trace!"); - // Case 1. If it has 1 source S on the trace, replace its uses - // with S. - if (onTraceSources == 1) { - DEBUG(std::cerr << "Replacing Phi node" << *PN - << " with its lone on-trace input " - << *PN->getIncomingValue (lastSrcFound) << "\n"); - PN->replaceAllUsesWith (PN->getIncomingValue (lastSrcFound)); - dstB->getInstList ().erase (BI); // Delete the non-used Phi node - } else { - // Case N. If it has >1 source on the trace, just delete - // sources from the Phi node that are not on the trace. - int lastOffTraceSrcFound = -1; - do { - for (unsigned i = 0; i < PN->getNumIncomingValues (); ++i) - if (PN->getIncomingBlock (i)->getParent () != F) { - lastOffTraceSrcFound = i; // Found an off-trace source. - break; - } - if (lastOffTraceSrcFound != -1) { // Found one? - DEBUG(std::cerr << "Removing off-trace input " - << *PN->getIncomingValue (lastOffTraceSrcFound) - << " from Phi node " << *PN << "\n"); - PN->removeIncomingValue (lastOffTraceSrcFound); // Delete it. - } - } while (lastOffTraceSrcFound != -1); // Continue until none found. - } - } - // Make sure that our Phi fixups did the Right Thing. - DEBUG(if (PHINode *PN = dyn_cast (&I)) - for (unsigned i = 0; i < PN->getNumIncomingValues (); ++i) - assert (PN->getIncomingBlock (i)->getParent () == F && - "Sorry, copyTraceIntoFunction mishandled a Phi node")); - } - - // Remove calls to first-level instrumentation if we find them. - for (BasicBlock::iterator BI = dstB->begin (), BE = dstB->end (); - BI != BE; ++BI) { - Instruction &I = *BI; - if (CallInst *CI = dyn_cast (&I)) { - Function *CF = CI->getCalledFunction (); - if (CF->getName () == "llvm_first_trigger" && CF->isExternal ()) { - DEBUG(std::cerr << " (Found a call instruction " << *CI - << " ... Smells like llvm_first_trigger.)\n"); - dstB->getInstList ().erase (BI); - } - } } } From lattner at cs.uiuc.edu Fri Aug 29 00:30:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 29 00:30:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Linker/2003-08-28-TypeResolvesGlobal3.ll Message-ID: <200308290529.AAA14512@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Linker: 2003-08-28-TypeResolvesGlobal3.ll added (r1.1) --- Log message: Yet ANOTHER complication that the libstdc++ library runs into linking... --- Diffs of the changes: Index: llvm/test/Regression/Linker/2003-08-28-TypeResolvesGlobal3.ll diff -c /dev/null llvm/test/Regression/Linker/2003-08-28-TypeResolvesGlobal3.ll:1.1 *** /dev/null Fri Aug 29 00:29:48 2003 --- llvm/test/Regression/Linker/2003-08-28-TypeResolvesGlobal3.ll Fri Aug 29 00:29:38 2003 *************** *** 0 **** --- 1,15 ---- + ; RUN: as < %s > Output/%s.out1.bc + ; RUN: echo "%S = type int" | as > Output/%s.out2.bc + ; RUN: link Output/%s.out[21].bc + + %S = type opaque + + ; GLobal using the resolved function prototype + global void(%S*)* %foo + + void %foo(int* %V) { + ret void + } + + declare void %foo(%S*) + From lattner at cs.uiuc.edu Fri Aug 29 00:37:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 29 00:37:02 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Constant.h Constants.h Message-ID: <200308290536.AAA23255@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Constant.h updated: 1.8 -> 1.9 Constants.h updated: 1.28 -> 1.29 --- Log message: Allow for "unsafe" replaceAllUsesWith operatations, for use during type resolution --- Diffs of the changes: Index: llvm/include/llvm/Constant.h diff -u llvm/include/llvm/Constant.h:1.8 llvm/include/llvm/Constant.h:1.9 --- llvm/include/llvm/Constant.h:1.8 Sat Jun 21 22:07:32 2003 +++ llvm/include/llvm/Constant.h Fri Aug 29 00:36:05 2003 @@ -67,7 +67,8 @@ /// use Value::replaceAllUsesWith, which automatically dispatches to this /// method as needed. /// - virtual void replaceUsesOfWithOnConstant(Value *From, Value *To) { + virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, + bool DisableChecking = false) { // Provide a default implementation for constants (like integers) that // cannot use any other values. This cannot be called at runtime, but needs // to be here to avoid link errors. Index: llvm/include/llvm/Constants.h diff -u llvm/include/llvm/Constants.h:1.28 llvm/include/llvm/Constants.h:1.29 --- llvm/include/llvm/Constants.h:1.28 Wed Jul 23 09:49:06 2003 +++ llvm/include/llvm/Constants.h Fri Aug 29 00:36:05 2003 @@ -315,7 +315,8 @@ } virtual void destroyConstant(); - virtual void replaceUsesOfWithOnConstant(Value *From, Value *To); + virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, + bool DisableChecking = false); /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ConstantArray *) { return true; } @@ -362,7 +363,8 @@ } virtual void destroyConstant(); - virtual void replaceUsesOfWithOnConstant(Value *From, Value *To); + virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, + bool DisableChecking = false); /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ConstantStruct *) { return true; } @@ -456,7 +458,8 @@ } virtual void destroyConstant(); - virtual void replaceUsesOfWithOnConstant(Value *From, Value *To); + virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, + bool DisableChecking = false); /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ConstantPointerRef *) { return true; } @@ -526,7 +529,8 @@ virtual bool isConstantExpr() const { return true; } virtual void destroyConstant(); - virtual void replaceUsesOfWithOnConstant(Value *From, Value *To); + virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, + bool DisableChecking = false); /// Override methods to provide more type information... inline Constant *getOperand(unsigned i) { From lattner at cs.uiuc.edu Fri Aug 29 00:38:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 29 00:38:02 2003 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Value.cpp Message-ID: <200308290537.AAA23373@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Value.cpp updated: 1.33 -> 1.34 --- Log message: Fix bug: Linker/2003-08-28-TypeResolvesGlobal3.ll Use new replaceAllUsesWith stuff in a way that works even though types have not yet been propagated --- Diffs of the changes: Index: llvm/lib/VMCore/Value.cpp diff -u llvm/lib/VMCore/Value.cpp:1.33 llvm/lib/VMCore/Value.cpp:1.34 --- llvm/lib/VMCore/Value.cpp:1.33 Fri Aug 29 00:09:37 2003 +++ llvm/lib/VMCore/Value.cpp Fri Aug 29 00:37:22 2003 @@ -78,7 +78,7 @@ // Must handle Constants specially, we cannot call replaceUsesOfWith on a // constant! if (Constant *C = dyn_cast(Use)) { - C->replaceUsesOfWithOnConstant(this, New); + C->replaceUsesOfWithOnConstant(this, New, true); } else { Use->replaceUsesOfWith(this, New); } From lattner at cs.uiuc.edu Fri Aug 29 00:38:10 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 29 00:38:10 2003 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200308290537.AAA23271@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.51 -> 1.52 --- Log message: Implement "unsafe" replaceAllUsesWWith stuff for use during type resolution. --- Diffs of the changes: Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.51 llvm/lib/VMCore/Constants.cpp:1.52 --- llvm/lib/VMCore/Constants.cpp:1.51 Fri Aug 29 00:09:37 2003 +++ llvm/lib/VMCore/Constants.cpp Fri Aug 29 00:36:46 2003 @@ -350,9 +350,6 @@ // TODO: Figure out how to test if a double can be cast to a float! case Type::FloatTyID: - /* - return (Val <= UINT8_MAX); - */ case Type::DoubleTyID: return true; // This is the largest type... } @@ -361,7 +358,8 @@ //===----------------------------------------------------------------------===// // replaceUsesOfWithOnConstant implementations -void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To) { +void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, + bool DisableChecking) { assert(isa(To) && "Cannot make Constant refer to non-constant!"); std::vector Values; @@ -376,13 +374,17 @@ assert(Replacement != this && "I didn't contain From!"); // Everyone using this now uses the replacement... - replaceAllUsesWith(Replacement); + if (DisableChecking) + uncheckedReplaceAllUsesWith(Replacement); + else + replaceAllUsesWith(Replacement); // Delete the old constant! destroyConstant(); } -void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To) { +void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, + bool DisableChecking) { assert(isa(To) && "Cannot make Constant refer to non-constant!"); std::vector Values; @@ -397,33 +399,42 @@ assert(Replacement != this && "I didn't contain From!"); // Everyone using this now uses the replacement... - replaceAllUsesWith(Replacement); + if (DisableChecking) + uncheckedReplaceAllUsesWith(Replacement); + else + replaceAllUsesWith(Replacement); // Delete the old constant! destroyConstant(); } -void ConstantPointerRef::replaceUsesOfWithOnConstant(Value *From, Value *To) { +void ConstantPointerRef::replaceUsesOfWithOnConstant(Value *From, Value *To, + bool DisableChecking) { if (isa(To)) { assert(From == getOperand(0) && "Doesn't contain from!"); ConstantPointerRef *Replacement = ConstantPointerRef::get(cast(To)); // Everyone using this now uses the replacement... - replaceAllUsesWith(Replacement); + if (DisableChecking) + uncheckedReplaceAllUsesWith(Replacement); + else + replaceAllUsesWith(Replacement); - // Delete the old constant! - destroyConstant(); } else { // Just replace ourselves with the To value specified. - replaceAllUsesWith(To); - - // Delete the old constant! - destroyConstant(); + if (DisableChecking) + uncheckedReplaceAllUsesWith(To); + else + replaceAllUsesWith(To); } + + // Delete the old constant! + destroyConstant(); } -void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV) { +void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, + bool DisableChecking) { assert(isa(ToV) && "Cannot make Constant refer to non-constant!"); Constant *To = cast(ToV); @@ -457,7 +468,10 @@ assert(Replacement != this && "I didn't contain From!"); // Everyone using this now uses the replacement... - replaceAllUsesWith(Replacement); + if (DisableChecking) + uncheckedReplaceAllUsesWith(Replacement); + else + replaceAllUsesWith(Replacement); // Delete the old constant! destroyConstant(); From lattner at cs.uiuc.edu Fri Aug 29 09:08:15 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 29 09:08:15 2003 Subject: [llvm-commits] CVS: llvm/Makefile.common Message-ID: <200308291407.JAA29545@apoc.cs.uiuc.edu> Changes in directory llvm: Makefile.common updated: 1.130 -> 1.131 --- Log message: Slightly simplify make logic --- Diffs of the changes: Index: llvm/Makefile.common diff -u llvm/Makefile.common:1.130 llvm/Makefile.common:1.131 --- llvm/Makefile.common:1.130 Thu Aug 28 16:45:08 2003 +++ llvm/Makefile.common Fri Aug 29 09:07:02 2003 @@ -843,9 +843,7 @@ # ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),distclean) -ifneq ($(SourceDepend),) --include $(SourceDepend) -endif +-include /dev/null $(SourceDepend) endif endif From lattner at cs.uiuc.edu Fri Aug 29 09:23:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 29 09:23:02 2003 Subject: [llvm-commits] CVS: llvm/include/Support/ilist Message-ID: <200308291422.JAA21661@neo.cs.uiuc.edu> Changes in directory llvm/include/Support: ilist updated: 1.9 -> 1.10 --- Log message: Fix compilation problems with G++ 3.4 --- Diffs of the changes: Index: llvm/include/Support/ilist diff -u llvm/include/Support/ilist:1.9 llvm/include/Support/ilist:1.10 --- llvm/include/Support/ilist:1.9 Fri Jul 25 12:23:13 2003 +++ llvm/include/Support/ilist Fri Aug 29 09:22:29 2003 @@ -198,7 +198,7 @@ typedef std::reverse_iterator const_reverse_iterator; typedef std::reverse_iterator reverse_iterator; - iplist() : Head(createNode()), Tail(Head) { + iplist() : Head(this->createNode()), Tail(Head) { setNext(Head, 0); setPrev(Head, 0); } @@ -441,16 +441,16 @@ ilist() {} ilist(const ilist &right) { - insert(begin(), right.begin(), right.end()); + insert(this->begin(), right.begin(), right.end()); } explicit ilist(size_type count) { - insert(begin(), count, NodeTy()); + insert(this->begin(), count, NodeTy()); } ilist(size_type count, const NodeTy &val) { - insert(begin(), count, val); + insert(this->begin(), count, val); } template ilist(InIt first, InIt last) { - insert(begin(), first, last); + insert(this->begin(), first, last); } @@ -469,8 +469,8 @@ // Front and back inserters... - void push_front(const NodeTy &val) { insert(begin(), val); } - void push_back(const NodeTy &val) { insert(end(), val); } + void push_front(const NodeTy &val) { insert(this->begin(), val); } + void push_back(const NodeTy &val) { insert(this->end(), val); } // Special forms of insert... template void insert(iterator where, InIt first, InIt last) { @@ -482,16 +482,16 @@ // Assign special forms... void assign(size_type count, const NodeTy &val) { - iterator I = begin(); - for (; I != end() && count != 0; ++I, --count) + iterator I = this->begin(); + for (; I != this->end() && count != 0; ++I, --count) *I = val; if (count != 0) - insert(end(), n, val); + insert(this->end(), val, val); else - erase(I, end()); + erase(I, this->end()); } - template void assign(InIt first, InIt last) { - iterator first1 = begin(), last1 = end(); + template void assign(InIt first1, InIt last1) { + iterator first2 = this->begin(), last2 = this->end(); for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) *first1 = *first2; if (first2 == last2) @@ -503,14 +503,14 @@ // Resize members... void resize(size_type newsize, NodeTy val) { - iterator i = begin(); + iterator i = this->begin(); size_type len = 0; - for ( ; i != end() && len < newsize; ++i, ++len) /* empty*/ ; + for ( ; i != this->end() && len < newsize; ++i, ++len) /* empty*/ ; if (len == newsize) - erase(i, end()); + erase(i, this->end()); else // i == end() - insert(end(), newsize - len, val); + insert(this->end(), newsize - len, val); } void resize(size_type newsize) { resize(newsize, NodeTy()); } }; From lattner at cs.uiuc.edu Fri Aug 29 09:28:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 29 09:28:03 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/PassAnalysisSupport.h Pass.h Message-ID: <200308291427.JAA21683@neo.cs.uiuc.edu> Changes in directory llvm/include/llvm: PassAnalysisSupport.h updated: 1.13 -> 1.14 Pass.h updated: 1.37 -> 1.38 --- Log message: Move getAnalysisToUpdate to after the definition of AnalysisResolver. GCC 3.4 apparently wants classes to be DEFINED before they are USED. What is it smoking. --- Diffs of the changes: Index: llvm/include/llvm/PassAnalysisSupport.h diff -u llvm/include/llvm/PassAnalysisSupport.h:1.13 llvm/include/llvm/PassAnalysisSupport.h:1.14 --- llvm/include/llvm/PassAnalysisSupport.h:1.13 Sat Jun 21 22:07:32 2003 +++ llvm/include/llvm/PassAnalysisSupport.h Fri Aug 29 09:26:51 2003 @@ -110,4 +110,20 @@ void setAnalysisResolver(Pass *P, AnalysisResolver *AR); }; +/// getAnalysisToUpdate() - This function is used by subclasses +/// to get to the analysis information that might be around that needs to be +/// updated. This is different than getAnalysis in that it can fail (ie the +/// analysis results haven't been computed), so should only be used if you +/// provide the capability to update an analysis that exists. This method is +/// often used by transformation APIs to update analysis results for a pass +/// automatically as the transform is performed. +/// +template +AnalysisType *Pass::getAnalysisToUpdate() const { + assert(Resolver && "Pass not resident in a PassManager object!"); + const PassInfo *PI = getClassPassInfo(); + if (PI == 0) return 0; + return dynamic_cast(Resolver->getAnalysisToUpdate(PI)); +} + #endif Index: llvm/include/llvm/Pass.h diff -u llvm/include/llvm/Pass.h:1.37 llvm/include/llvm/Pass.h:1.38 --- llvm/include/llvm/Pass.h:1.37 Mon Aug 18 09:27:03 2003 +++ llvm/include/llvm/Pass.h Fri Aug 29 09:26:51 2003 @@ -136,12 +136,7 @@ /// automatically as the transform is performed. /// template - AnalysisType *getAnalysisToUpdate() const { - assert(Resolver && "Pass not resident in a PassManager object!"); - const PassInfo *PI = getClassPassInfo(); - if (PI == 0) return 0; - return dynamic_cast(Resolver->getAnalysisToUpdate(PI)); - } + AnalysisType *getAnalysisToUpdate() const; // Defined in PassAnalysisSupport.h /// mustPreserveAnalysisID - This method serves the same function as /// getAnalysisToUpdate, but works if you just have an AnalysisID. This From lattner at cs.uiuc.edu Fri Aug 29 09:44:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 29 09:44:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/InstCount.cpp Message-ID: <200308291443.JAA11360@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: InstCount.cpp updated: 1.4 -> 1.5 --- Log message: There is no reason for this to be a pass! --- Diffs of the changes: Index: llvm/lib/Analysis/InstCount.cpp diff -u llvm/lib/Analysis/InstCount.cpp:1.4 llvm/lib/Analysis/InstCount.cpp:1.5 --- llvm/lib/Analysis/InstCount.cpp:1.4 Sat Dec 7 17:24:24 2002 +++ llvm/lib/Analysis/InstCount.cpp Fri Aug 29 09:43:17 2003 @@ -5,7 +5,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Pass.h" -#include "llvm/Module.h" +#include "llvm/Function.h" #include "llvm/Support/InstVisitor.h" #include "Support/Statistic.h" @@ -19,7 +19,7 @@ #include "llvm/Instruction.def" - class InstCount : public Pass, public InstVisitor { + class InstCount : public FunctionPass, public InstVisitor { friend class InstVisitor; void visitFunction (Function &F) { ++TotalFuncs; } @@ -35,7 +35,7 @@ abort(); } public: - virtual bool run(Module &M); + virtual bool runOnFunction(Function &F); virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); @@ -51,7 +51,7 @@ // InstCount::run - This is the main Analysis entry point for a // function. // -bool InstCount::run(Module &M) { - visit(M); +bool InstCount::runOnFunction(Function &F) { + visit(F); return false; } From criswell at cs.uiuc.edu Fri Aug 29 09:47:01 2003 From: criswell at cs.uiuc.edu (John Criswell) Date: Fri Aug 29 09:47:01 2003 Subject: [llvm-commits] CVS: llvm/tools/gccld/gccld.cpp Message-ID: <200308291446.JAA21435@choi.cs.uiuc.edu> Changes in directory llvm/tools/gccld: gccld.cpp updated: 1.41 -> 1.42 --- Log message: "Help keep our secrets secret." Added code to respect the umask value. Before, files were generated world readable, which may not be desirable for all installations. --- Diffs of the changes: Index: llvm/tools/gccld/gccld.cpp diff -u llvm/tools/gccld/gccld.cpp:1.41 llvm/tools/gccld/gccld.cpp:1.42 --- llvm/tools/gccld/gccld.cpp:1.41 Fri Aug 22 14:18:45 2003 +++ llvm/tools/gccld/gccld.cpp Fri Aug 29 09:46:12 2003 @@ -433,6 +433,9 @@ Out.close(); if (!LinkAsLibrary) { + // Permissions masking value of the user + mode_t mask; + // Output the script to start the program... std::ofstream Out2(OutputFilename.c_str()); if (!Out2.good()) @@ -441,11 +444,22 @@ Out2 << "#!/bin/sh\nlli -q -abort-on-exception $0.bc $*\n"; Out2.close(); + // + // Grab the umask value from the operating system. We want to use it when + // changing the file's permissions. + // + // Note: + // Umask() is one of those annoying system calls. You have to call it + // to get the current value and then set it back. + // + mask = umask (0); + umask (mask); + // Make the script executable... - chmod(OutputFilename.c_str(), 0755); + chmod(OutputFilename.c_str(), (0755 & ~mask)); // Make the bytecode file directly executable in LLEE as well - chmod(RealBytecodeOutput.c_str(), 0755); + chmod(RealBytecodeOutput.c_str(), (0755 & ~mask)); } return 0; From lattner at cs.uiuc.edu Fri Aug 29 09:49:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 29 09:49:03 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Support/InstVisitor.h Message-ID: <200308291448.JAA21744@neo.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: InstVisitor.h updated: 1.19 -> 1.20 --- Log message: Remove automagic support for Modules. Noone uses it now anyways, and GCC 3.4 doesn't want us to do this unless Module has been #included --- Diffs of the changes: Index: llvm/include/llvm/Support/InstVisitor.h diff -u llvm/include/llvm/Support/InstVisitor.h:1.19 llvm/include/llvm/Support/InstVisitor.h:1.20 --- llvm/include/llvm/Support/InstVisitor.h:1.19 Mon Aug 18 09:28:20 2003 +++ llvm/include/llvm/Support/InstVisitor.h Fri Aug 29 09:48:21 2003 @@ -78,12 +78,8 @@ ((SubClass*)this)->visit(*Start++); } - // Define visitors for modules, functions and basic blocks... + // Define visitors for functions and basic blocks... // - void visit(Module &M) { - ((SubClass*)this)->visitModule(M); - visit(M.begin(), M.end()); - } void visit(Function &F) { ((SubClass*)this)->visitFunction(F); visit(F.begin(), F.end()); @@ -123,7 +119,6 @@ // When visiting a module, function or basic block directly, these methods get // called to indicate when transitioning into a new unit. // - void visitModule (Module &M) {} void visitFunction (Function &F) {} void visitBasicBlock(BasicBlock &BB) {} From brukman at cs.uiuc.edu Fri Aug 29 10:27:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Aug 29 10:27:01 2003 Subject: [llvm-commits] CVS: llvm/test/Makefile.tests Message-ID: <200308291526.KAA31176@zion.cs.uiuc.edu> Changes in directory llvm/test: Makefile.tests updated: 1.76 -> 1.77 --- Log message: Use `llvm-dis' instead of simply `dis'. --- Diffs of the changes: Index: llvm/test/Makefile.tests diff -u llvm/test/Makefile.tests:1.76 llvm/test/Makefile.tests:1.77 --- llvm/test/Makefile.tests:1.76 Fri Aug 22 09:09:46 2003 +++ llvm/test/Makefile.tests Fri Aug 29 10:26:31 2003 @@ -47,7 +47,7 @@ LGCCAS = $(TOOLS)/gccas LGCCLD = $(TOOLS)/gccld -L$(LLVMGCCDIR)/lib/gcc/$(LLVMGCCARCH) -L$(LLVMGCCDIR)/lib LGCCLDPROG = $(TOOLS)/gccld -LDIS = $(TOOLS)/dis +LDIS = $(TOOLS)/llvm-dis LOPT = $(TOOLS)/opt LLINK = $(TOOLS)/link LANALYZE = $(TOOLS)/analyze From lattner at cs.uiuc.edu Fri Aug 29 11:01:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 29 11:01:02 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/CompileFail/2003-08-29-ArgPassingBug.cpp.tr Message-ID: <200308291600.LAA24790@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend/CompileFail: 2003-08-29-ArgPassingBug.cpp.tr added (r1.1) --- Log message: New testcase --- Diffs of the changes: Index: llvm/test/Regression/C++Frontend/CompileFail/2003-08-29-ArgPassingBug.cpp.tr diff -c /dev/null llvm/test/Regression/C++Frontend/CompileFail/2003-08-29-ArgPassingBug.cpp.tr:1.1 *** /dev/null Fri Aug 29 11:00:29 2003 --- llvm/test/Regression/C++Frontend/CompileFail/2003-08-29-ArgPassingBug.cpp.tr Fri Aug 29 11:00:19 2003 *************** *** 0 **** --- 1,13 ---- + + // RUN: llvmgcc -xc++ -c -o /dev/null %s 2>&1 | not grep WARNING + + struct iterator { + iterator(); + iterator(const iterator &I); + }; + + iterator foo(const iterator &I) { return I; } + + void test() { + foo(iterator()); + } From lattner at cs.uiuc.edu Fri Aug 29 11:10:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 29 11:10:02 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/TEST.nightly.report Message-ID: <200308291609.LAA21857@neo.cs.uiuc.edu> Changes in directory llvm/test/Programs: TEST.nightly.report updated: 1.14 -> 1.15 --- Log message: ADd support for 1:23.45 style times --- Diffs of the changes: Index: llvm/test/Programs/TEST.nightly.report diff -u llvm/test/Programs/TEST.nightly.report:1.14 llvm/test/Programs/TEST.nightly.report:1.15 --- llvm/test/Programs/TEST.nightly.report:1.14 Thu Aug 28 10:50:29 2003 +++ llvm/test/Programs/TEST.nightly.report Fri Aug 29 11:09:29 2003 @@ -43,9 +43,9 @@ ["JIT
    codegen" , "TEST-RESULT-jit-comptime: $WallTimeRE"], ["Machine
    code", 'TEST-RESULT-jit-machcode: *([0-9]+).*bytes of machine code'], [], - ["GCC" , 'TEST-RESULT-nat-time: real\s*([.0-9m]+)', \&FormatTime], - ["CBE" , 'TEST-RESULT-cbe-time: real\s*([.0-9m]+)', \&FormatTime], - ["LLC" , 'TEST-RESULT-llc-time: real\s*([.0-9m]+)', \&FormatTime], - ["JIT" , 'TEST-RESULT-jit-time: real\s*([.0-9m]+)', \&FormatTime], + ["GCC" , 'TEST-RESULT-nat-time: real\s*([.0-9m:]+)', \&FormatTime], + ["CBE" , 'TEST-RESULT-cbe-time: real\s*([.0-9m:]+)', \&FormatTime], + ["LLC" , 'TEST-RESULT-llc-time: real\s*([.0-9m:]+)', \&FormatTime], + ["JIT" , 'TEST-RESULT-jit-time: real\s*([.0-9m:]+)', \&FormatTime], ["GCC/LLC" , \&GCCLLCRatio] ); From lattner at cs.uiuc.edu Fri Aug 29 11:14:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 29 11:14:01 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/TEST.nightly.report Message-ID: <200308291613.LAA21907@neo.cs.uiuc.edu> Changes in directory llvm/test/Programs: TEST.nightly.report updated: 1.15 -> 1.16 --- Log message: Reduce "precision" --- Diffs of the changes: Index: llvm/test/Programs/TEST.nightly.report diff -u llvm/test/Programs/TEST.nightly.report:1.15 llvm/test/Programs/TEST.nightly.report:1.16 --- llvm/test/Programs/TEST.nightly.report:1.15 Fri Aug 29 11:09:29 2003 +++ llvm/test/Programs/TEST.nightly.report Fri Aug 29 11:13:20 2003 @@ -13,7 +13,7 @@ sub FormatTime { my $Time = shift; if ($Time =~ m/([0-9]+)[m:]([0-9.]+)/) { - $Time = sprintf("%7.4f", $1*60.0+$2); + $Time = sprintf("%7.3f", $1*60.0+$2); } return $Time; } From brukman at cs.uiuc.edu Fri Aug 29 13:10:02 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Aug 29 13:10:02 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libtermcap/Makefile dummy.c Message-ID: <200308291809.NAA06996@zion.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libtermcap: Makefile added (r1.1) dummy.c added (r1.1) --- Log message: Added dummy termcap library. --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libtermcap/Makefile diff -c /dev/null llvm/runtime/GCCLibraries/libtermcap/Makefile:1.1 *** /dev/null Fri Aug 29 13:09:56 2003 --- llvm/runtime/GCCLibraries/libtermcap/Makefile Fri Aug 29 13:09:46 2003 *************** *** 0 **** --- 1,6 ---- + LEVEL = ../../.. + BYTECODE_LIBRARY=1 + DONT_BUILD_RELINKED=1 + LIBRARYNAME=termcap + + include $(LEVEL)/Makefile.common From brukman at cs.uiuc.edu Fri Aug 29 13:10:12 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Aug 29 13:10:12 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libtermcap/ Message-ID: <200308291809.NAA06979@zion.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libtermcap: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/runtime/GCCLibraries/libtermcap added to the repository --- Diffs of the changes: From brukman at cs.uiuc.edu Fri Aug 29 13:14:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Aug 29 13:14:01 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libcurses/ Message-ID: <200308291813.NAA19344@zion.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libcurses: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/runtime/GCCLibraries/libcurses added to the repository --- Diffs of the changes: From brukman at cs.uiuc.edu Fri Aug 29 13:15:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Aug 29 13:15:01 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libcurses/Makefile dummy.c Message-ID: <200308291814.NAA20253@zion.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libcurses: Makefile added (r1.1) dummy.c added (r1.1) --- Log message: Added a dummy version of libcurses. --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libcurses/Makefile diff -c /dev/null llvm/runtime/GCCLibraries/libcurses/Makefile:1.1 *** /dev/null Fri Aug 29 13:14:02 2003 --- llvm/runtime/GCCLibraries/libcurses/Makefile Fri Aug 29 13:13:52 2003 *************** *** 0 **** --- 1,6 ---- + LEVEL = ../../.. + BYTECODE_LIBRARY=1 + DONT_BUILD_RELINKED=1 + LIBRARYNAME=curses + + include $(LEVEL)/Makefile.common From brukman at cs.uiuc.edu Fri Aug 29 16:29:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Aug 29 16:29:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2003-08-29-HugeCharConst.c Message-ID: <200308292128.QAA16587@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2003-08-29-HugeCharConst.c added (r1.1) --- Log message: Testcase distilled from xemacs. --- Diffs of the changes: Index: llvm/test/Regression/CFrontend/2003-08-29-HugeCharConst.c diff -c /dev/null llvm/test/Regression/CFrontend/2003-08-29-HugeCharConst.c:1.1 *** /dev/null Fri Aug 29 16:28:58 2003 --- llvm/test/Regression/CFrontend/2003-08-29-HugeCharConst.c Fri Aug 29 16:28:47 2003 *************** *** 0 **** --- 1,3 ---- + void foo() { + unsigned char int_latin1[] = "f\200\372b\200\343\200\340"; + } From brukman at cs.uiuc.edu Fri Aug 29 16:51:01 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Aug 29 16:51:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2003-08-29-BitFieldStruct.c Message-ID: <200308292150.QAA05609@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2003-08-29-BitFieldStruct.c added (r1.1) --- Log message: Test case distilled from sed. --- Diffs of the changes: Index: llvm/test/Regression/CFrontend/2003-08-29-BitFieldStruct.c diff -c /dev/null llvm/test/Regression/CFrontend/2003-08-29-BitFieldStruct.c:1.1 *** /dev/null Fri Aug 29 16:50:01 2003 --- llvm/test/Regression/CFrontend/2003-08-29-BitFieldStruct.c Fri Aug 29 16:49:51 2003 *************** *** 0 **** --- 1,14 ---- + typedef enum { FALSE, TRUE } flagT; + + struct Word + { + short bar; + short baz; + flagT final:1; + short quux; + } *word_limit; + + void foo () + { + word_limit->final = (word_limit->final && word_limit->final); + } From lattner at cs.uiuc.edu Fri Aug 29 16:58:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 29 16:58:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2003-08-29-BitFieldStruct.c Message-ID: <200308292157.QAA09997@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2003-08-29-BitFieldStruct.c updated: 1.1 -> 1.2 --- Log message: minor simplification --- Diffs of the changes: Index: llvm/test/Regression/CFrontend/2003-08-29-BitFieldStruct.c diff -u llvm/test/Regression/CFrontend/2003-08-29-BitFieldStruct.c:1.1 llvm/test/Regression/CFrontend/2003-08-29-BitFieldStruct.c:1.2 --- llvm/test/Regression/CFrontend/2003-08-29-BitFieldStruct.c:1.1 Fri Aug 29 16:49:51 2003 +++ llvm/test/Regression/CFrontend/2003-08-29-BitFieldStruct.c Fri Aug 29 16:57:18 2003 @@ -1,10 +1,7 @@ -typedef enum { FALSE, TRUE } flagT; - -struct Word -{ +struct Word { short bar; short baz; - flagT final:1; + int final:1; short quux; } *word_limit; From lattner at cs.uiuc.edu Fri Aug 29 17:47:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Aug 29 17:47:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2003-08-29-StructLayoutBug.c Message-ID: <200308292246.RAA13059@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2003-08-29-StructLayoutBug.c added (r1.1) --- Log message: Yet another bit-field bug --- Diffs of the changes: Index: llvm/test/Regression/CFrontend/2003-08-29-StructLayoutBug.c diff -c /dev/null llvm/test/Regression/CFrontend/2003-08-29-StructLayoutBug.c:1.1 *** /dev/null Fri Aug 29 17:46:44 2003 --- llvm/test/Regression/CFrontend/2003-08-29-StructLayoutBug.c Fri Aug 29 17:46:34 2003 *************** *** 0 **** --- 1,8 ---- + struct foo { + unsigned int I:1; + unsigned char J[1]; + unsigned int K:1; + }; + + void test(struct foo *X) {} + From lattner at cs.uiuc.edu Sat Aug 30 15:58:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 15:58:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2003-08-30-AggregateInitializer.c Message-ID: <200308302057.PAA20931@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2003-08-30-AggregateInitializer.c added (r1.1) --- Log message: New, HARD, bitfield testcase --- Diffs of the changes: Index: llvm/test/Regression/CFrontend/2003-08-30-AggregateInitializer.c diff -c /dev/null llvm/test/Regression/CFrontend/2003-08-30-AggregateInitializer.c:1.1 *** /dev/null Sat Aug 30 15:57:59 2003 --- llvm/test/Regression/CFrontend/2003-08-30-AggregateInitializer.c Sat Aug 30 15:57:49 2003 *************** *** 0 **** --- 1,15 ---- + + struct istruct { + unsigned char C; + }; + + struct foo { + unsigned int I:1; + struct istruct J; + unsigned char L[1]; + unsigned int K:1; + }; + + struct foo F = { 1, { 7 }, { 123 } , 1 }; + + From lattner at cs.uiuc.edu Sat Aug 30 16:01:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 16:01:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2003-08-30-LargeIntegerBitfieldMember.c Message-ID: <200308302100.QAA21200@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2003-08-30-LargeIntegerBitfieldMember.c added (r1.1) --- Log message: New testcase *sigh* --- Diffs of the changes: Index: llvm/test/Regression/CFrontend/2003-08-30-LargeIntegerBitfieldMember.c diff -c /dev/null llvm/test/Regression/CFrontend/2003-08-30-LargeIntegerBitfieldMember.c:1.1 *** /dev/null Sat Aug 30 16:00:46 2003 --- llvm/test/Regression/CFrontend/2003-08-30-LargeIntegerBitfieldMember.c Sat Aug 30 16:00:36 2003 *************** *** 0 **** --- 1,8 ---- + + struct foo { + unsigned int I:1; + unsigned char J[1][123]; + unsigned int K:1; + }; + + struct foo F; From lattner at cs.uiuc.edu Sat Aug 30 17:38:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 17:38:01 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h Message-ID: <200308302237.RAA21553@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: SJLJ-Exception.h added (r1.1) --- Log message: Initial checkin of the SJLJ EH interface --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h diff -c /dev/null llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h:1.1 *** /dev/null Sat Aug 30 17:37:03 2003 --- llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h Sat Aug 30 17:36:52 2003 *************** *** 0 **** --- 1,74 ---- + //===- SJLJ-exception.h - SetJmp/LongJmp Exception Handling -----*- C++ -*-===// + // + // This file defines the data structures and API used by the Setjmp/Longjmp + // exception handling runtime library. + // + //===----------------------------------------------------------------------===// + + #ifndef SJLJ_EXCEPTION_H + #define SJLJ_EXCEPTION_H + + #include "exception.h" + #include + + struct llvm_sjlj_exception { + // JmpBuffer - This is the buffer which was longjmp'd with. + // + void *JmpBuffer; + + // LongJmpValue - The value passed into longjmp, which the corresponding + // setjmp should return. Note that this value will never be equal to 0. + // + int LongJmpValue; + + // BaseException - The language independent portion of the exception state. + // This is at the end of the record so that we can add additional members to + // this structure without breaking binary compatibility. + // + llvm_exception BaseException; + }; + + extern "C" { + // __llvm_sjljeh_throw_longjmp - This function creates the longjmp exception + // and returns. It takes care of mapping the longjmp value from 0 -> 1 as + // appropriate. The caller should immediately call llvm.unwind after this + // function call. + void __llvm_sjljeh_throw_longjmp(void *JmpBuffer, int Val) throw(); + + // __llvm_sjljeh_init_setjmpmap - This funciton initializes the pointer + // provided to an empty setjmp map, and should be called on entry to a + // function which calls setjmp. + void __llvm_sjljeh_init_setjmpmap(void **SetJmpMap) throw(); + + // __llvm_sjljeh_destroy_setjmpmap - This function frees all memory associated + // with the specified setjmpmap structure. It should be called on all exits + // (returns or unwinds) from the function which calls ...init_setjmpmap. + void __llvm_sjljeh_destroy_setjmpmap(void **SetJmpMap) throw(); + + // __llvm_sjljeh_add_setjmp_to_map - This function adds or updates an entry to + // the map, to indicate which setjmp should be returned to if a longjmp + // happens. + void __llvm_sjljeh_add_setjmp_to_map(void **SetJmpMap, void *JmpBuf, + unsigned SetJmpID) throw(); + + // __llvm_sjljeh_is_longjmp_exception - This function returns true if the + // current uncaught exception is a longjmp exception. This is the first step + // of catching a sjlj exception. + bool __llvm_sjljeh_is_longjmp_exception() throw(); + + // __llvm_sjljeh_get_longjmp_value - This function returns the value that the + // setjmp call should "return". This requires that the current uncaught + // exception be a sjlj exception, though it does not require the exception to + // be caught by this function. + int __llvm_sjljeh_get_longjmp_value() throw(); + + // __llvm_sjljeh_try_catching_longjmp_exception - This function checks to see + // if the current uncaught longjmp exception matches any of the setjmps + // collected in the setjmpmap structure. If so, it catches and destroys the + // exception, returning the index of the setjmp which caught the exception. + // If not, it leaves the exception uncaught and returns a value of ~0. + unsigned __llvm_sjljeh_try_catching_longjmp_exception(void **SetJmpMap) + throw(); + } + + #endif From lattner at cs.uiuc.edu Sat Aug 30 17:49:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 17:49:00 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/Exception.h Message-ID: <200308302248.RAA21678@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: Exception.h updated: 1.4 -> 1.5 --- Log message: File was renamed --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/Exception.h diff -u llvm/runtime/GCCLibraries/libexception/Exception.h:1.4 llvm/runtime/GCCLibraries/libexception/Exception.h:1.5 --- llvm/runtime/GCCLibraries/libexception/Exception.h:1.4 Thu Aug 28 14:58:51 2003 +++ llvm/runtime/GCCLibraries/libexception/Exception.h Sat Aug 30 17:48:16 2003 @@ -1,4 +1,4 @@ -//===- exception.h - Generic language-independent exceptions ----*- C++ -*-===// +//===- Exception.h - Generic language-independent exceptions ----*- C++ -*-===// // // This file defines the the shared data structures used by all language // specific exception handling runtime libraries. From lattner at cs.uiuc.edu Sat Aug 30 17:49:07 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 17:49:07 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/C++-Exception.cpp C++-Exception.h SJLJ-Exception.h Message-ID: <200308302248.RAA21667@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: C++-Exception.cpp updated: 1.6 -> 1.7 C++-Exception.h updated: 1.7 -> 1.8 SJLJ-Exception.h updated: 1.1 -> 1.2 --- Log message: Rename files to be capitalized now that they are C++ --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/C++-Exception.cpp diff -u llvm/runtime/GCCLibraries/libexception/C++-Exception.cpp:1.6 llvm/runtime/GCCLibraries/libexception/C++-Exception.cpp:1.7 --- llvm/runtime/GCCLibraries/libexception/C++-Exception.cpp:1.6 Thu Aug 28 14:58:51 2003 +++ llvm/runtime/GCCLibraries/libexception/C++-Exception.cpp Sat Aug 30 17:47:59 2003 @@ -1,4 +1,4 @@ -//===- c++-exception.cpp - Exception handling support for C++ exceptions --===// +//===- C++-Exception.cpp - Exception handling support for C++ exceptions --===// // // This file defines the methods used to implement C++ exception handling in // terms of the invoke and %llvm.unwind intrinsic. These primitives implement @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "c++-exception.h" +#include "C++-Exception.h" #include #include Index: llvm/runtime/GCCLibraries/libexception/C++-Exception.h diff -u llvm/runtime/GCCLibraries/libexception/C++-Exception.h:1.7 llvm/runtime/GCCLibraries/libexception/C++-Exception.h:1.8 --- llvm/runtime/GCCLibraries/libexception/C++-Exception.h:1.7 Thu Aug 28 14:58:51 2003 +++ llvm/runtime/GCCLibraries/libexception/C++-Exception.h Sat Aug 30 17:47:59 2003 @@ -1,4 +1,4 @@ -//===- c++-exception.h - C++ Specific exception Handling --------*- C++ -*-===// +//===- C++-Exception.h - C++ Specific Exception Handling --------*- C++ -*-===// // // This file defines the data structures and API used by the C++ exception // handling runtime library. @@ -8,7 +8,7 @@ #ifndef CXX_EXCEPTION_H #define CXX_EXCEPTION_H -#include "exception.h" +#include "Exception.h" #include #include Index: llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h diff -u llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h:1.1 llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h:1.2 --- llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h:1.1 Sat Aug 30 17:36:52 2003 +++ llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h Sat Aug 30 17:47:59 2003 @@ -1,4 +1,4 @@ -//===- SJLJ-exception.h - SetJmp/LongJmp Exception Handling -----*- C++ -*-===// +//===- SJLJ-Exception.h - SetJmp/LongJmp Exception Handling -----*- C++ -*-===// // // This file defines the data structures and API used by the Setjmp/Longjmp // exception handling runtime library. @@ -8,7 +8,7 @@ #ifndef SJLJ_EXCEPTION_H #define SJLJ_EXCEPTION_H -#include "exception.h" +#include "Exception.h" #include struct llvm_sjlj_exception { From lattner at cs.uiuc.edu Sat Aug 30 18:19:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 18:19:02 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/Exception.cpp Exception.h C++-Exception.cpp Message-ID: <200308302318.SAA03694@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: Exception.cpp added (r1.1) Exception.h updated: 1.5 -> 1.6 C++-Exception.cpp updated: 1.7 -> 1.8 --- Log message: Move language independent exception handling routines OUT of C++Exception.cpp --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/Exception.cpp diff -c /dev/null llvm/runtime/GCCLibraries/libexception/Exception.cpp:1.1 *** /dev/null Sat Aug 30 18:18:31 2003 --- llvm/runtime/GCCLibraries/libexception/Exception.cpp Sat Aug 30 18:17:51 2003 *************** *** 0 **** --- 1,57 ---- + //===- Exception.cpp - Generic language-independent exceptions ------------===// + // + // This file defines the the shared data structures used by all language + // specific exception handling runtime libraries. + // + //===----------------------------------------------------------------------===// + + #include "Exception.h" + #include + + // Thread local state for exception handling. FIXME: This should really be made + // thread-local! + + // UncaughtExceptionStack - The stack of exceptions currently being thrown. + static llvm_exception *UncaughtExceptionStack = 0; + + // __llvm_eh_has_uncaught_exception - This is used to implement + // std::uncaught_exception. + // + bool __llvm_eh_has_uncaught_exception() throw() { + return UncaughtExceptionStack != 0; + } + + // __llvm_eh_current_uncaught_exception - This function checks to see if the + // current uncaught exception is of the specified language type. If so, it + // returns a pointer to the exception area data. + // + void *__llvm_eh_current_uncaught_exception_type(unsigned HandlerType) throw() { + assert(UncaughtExceptionStack && "No uncaught exception!"); + if (UncaughtExceptionStack->ExceptionType == HandlerType) + return UncaughtExceptionStack+1; + return 0; + } + + // __llvm_eh_add_uncaught_exception - This adds the specified exception to the + // top of the uncaught exception stack. The exception should not already be on + // the stack! + void __llvm_eh_add_uncaught_exception(llvm_exception *E) throw() { + E->Next = UncaughtExceptionStack; + UncaughtExceptionStack = E; + } + + + // __llvm_eh_get_uncaught_exception - Returns the current uncaught exception. + // There must be an uncaught exception for this to work! + llvm_exception *__llvm_eh_get_uncaught_exception() throw() { + assert(UncaughtExceptionStack && "There are no uncaught exceptions!?!?"); + return UncaughtExceptionStack; + } + + // __llvm_eh_pop_from_uncaught_stack - Remove the current uncaught exception + // from the top of the stack. + llvm_exception *__llvm_eh_pop_from_uncaught_stack() throw() { + llvm_exception *E = __llvm_eh_get_uncaught_exception(); + UncaughtExceptionStack = E->Next; + return E; + } Index: llvm/runtime/GCCLibraries/libexception/Exception.h diff -u llvm/runtime/GCCLibraries/libexception/Exception.h:1.5 llvm/runtime/GCCLibraries/libexception/Exception.h:1.6 --- llvm/runtime/GCCLibraries/libexception/Exception.h:1.5 Sat Aug 30 17:48:16 2003 +++ llvm/runtime/GCCLibraries/libexception/Exception.h Sat Aug 30 18:17:51 2003 @@ -52,6 +52,10 @@ extern "C" { bool __llvm_eh_has_uncaught_exception() throw(); void *__llvm_eh_current_uncaught_exception_type(unsigned HandlerType) throw(); + void __llvm_eh_add_uncaught_exception(llvm_exception *E) throw(); + + llvm_exception *__llvm_eh_get_uncaught_exception() throw(); + llvm_exception *__llvm_eh_pop_from_uncaught_stack() throw(); } #endif Index: llvm/runtime/GCCLibraries/libexception/C++-Exception.cpp diff -u llvm/runtime/GCCLibraries/libexception/C++-Exception.cpp:1.7 llvm/runtime/GCCLibraries/libexception/C++-Exception.cpp:1.8 --- llvm/runtime/GCCLibraries/libexception/C++-Exception.cpp:1.7 Sat Aug 30 17:47:59 2003 +++ llvm/runtime/GCCLibraries/libexception/C++-Exception.cpp Sat Aug 30 18:17:51 2003 @@ -17,44 +17,14 @@ #include #endif -//===----------------------------------------------------------------------===// -// Generic exception support -// - -// Thread local state for exception handling. -// FIXME: This should really be made thread-local! -// - // LastCaughtException - The last exception caught by this handler. This is for // implementation of _rethrow and _get_last_caught. // -static llvm_exception *LastCaughtException = 0; - -// UncaughtExceptionStack - The stack of exceptions currently being thrown. -static llvm_exception *UncaughtExceptionStack = 0; - -// __llvm_eh_has_uncaught_exception - This is used to implement -// std::uncaught_exception. +// FIXME: This should be thread-local! // -bool __llvm_eh_has_uncaught_exception() throw() { - return UncaughtExceptionStack != 0; -} - -// __llvm_eh_current_uncaught_exception - This function checks to see if the -// current uncaught exception is of the specified language type. If so, it -// returns a pointer to the exception area data. -// -void *__llvm_eh_current_uncaught_exception_type(unsigned HandlerType) throw() { - assert(UncaughtExceptionStack && "No uncaught exception!"); - if (UncaughtExceptionStack->ExceptionType == HandlerType) - return UncaughtExceptionStack+1; - return 0; -} +static llvm_exception *LastCaughtException = 0; -//===----------------------------------------------------------------------===// -// C++ Specific exception handling support... -// using namespace __cxxabiv1; // __llvm_cxxeh_allocate_exception - This function allocates space for the @@ -113,8 +83,6 @@ llvm_cxx_exception *E = (llvm_cxx_exception *)ObjectPtr - 1; E->BaseException.ExceptionDestructor = cxx_destructor; E->BaseException.ExceptionType = CXXException; - E->BaseException.Next = UncaughtExceptionStack; - UncaughtExceptionStack = &E->BaseException; E->BaseException.HandlerCount = 0; E->BaseException.isRethrown = 0; @@ -122,6 +90,8 @@ E->ExceptionObjectDestructor = DtorPtr; E->UnexpectedHandler = __unexpected_handler; E->TerminateHandler = __terminate_handler; + + __llvm_eh_add_uncaught_exception(&E->BaseException); } @@ -163,16 +133,15 @@ // appropriate, otherwise it returns null. // void *__llvm_cxxeh_current_uncaught_exception_isa(void *CatchType) throw() { - assert(UncaughtExceptionStack && "No uncaught exception!"); - if (UncaughtExceptionStack->ExceptionType != CXXException) - return 0; // If it's not a c++ exception, it doesn't match! + void *EPtr = __llvm_eh_current_uncaught_exception_type(CXXException); + if (EPtr == 0) return 0; // If it's not a c++ exception, it doesn't match! // If it is a C++ exception, use the type info object stored in the exception // to see if TypeID matches and, if so, to adjust the exception object // pointer. // const std::type_info *Info = (const std::type_info *)CatchType; - return CXXExceptionISA(get_cxx_exception(UncaughtExceptionStack), Info); + return CXXExceptionISA((llvm_cxx_exception*)EPtr - 1, Info); } @@ -182,12 +151,8 @@ // function must work with foreign exceptions. // void *__llvm_cxxeh_begin_catch() throw() { - llvm_exception *E = UncaughtExceptionStack; - assert(UncaughtExceptionStack && "There are no uncaught exceptions!?!?"); + llvm_exception *E = __llvm_eh_pop_from_uncaught_stack(); - // The exception is now no longer uncaught. - UncaughtExceptionStack = E->Next; - // The exception is now caught. LastCaughtException = E; E->Next = 0; @@ -254,9 +219,9 @@ // time. void __llvm_cxxeh_call_terminate() throw() { void (*Handler)(void) = __terminate_handler; - if (UncaughtExceptionStack) - if (UncaughtExceptionStack->ExceptionType == CXXException) - Handler = get_cxx_exception(UncaughtExceptionStack)->TerminateHandler; + if (__llvm_eh_has_uncaught_exception()) + if (void *EPtr = __llvm_eh_current_uncaught_exception_type(CXXException)) + Handler = ((llvm_cxx_exception*)EPtr - 1)->TerminateHandler; __terminate(Handler); } @@ -279,8 +244,7 @@ // Add the exception to the top of the uncaught stack, to preserve the // invariant that the top of the uncaught stack is the current exception. - E->Next = UncaughtExceptionStack; - UncaughtExceptionStack = E; + __llvm_eh_add_uncaught_exception(E); // Return to the caller, which should perform the unwind now. } @@ -320,8 +284,6 @@ // void __llvm_cxxeh_check_eh_spec(void *Info, ...) { const std::type_info *TypeInfo = (const std::type_info *)Info; - llvm_exception *E = UncaughtExceptionStack; - assert(E && "No uncaught exceptions!"); if (TypeInfo == 0) { // Empty exception specification // Whatever exception this is, it is not allowed by the (empty) spec, call @@ -337,6 +299,9 @@ } } + llvm_exception *E = __llvm_eh_get_uncaught_exception(); + assert(E && "No uncaught exceptions!"); + // Check to see if the exception matches one of the types allowed by the // exception specification. If so, return to the caller to have the // exception rethrown. @@ -369,8 +334,7 @@ // Grab the newly caught exception. If this exception is permitted by the // specification, allow it to be thrown. - E = UncaughtExceptionStack; - assert(E && "No uncaught exceptions!"); + E = __llvm_eh_get_uncaught_exception(); va_start(Args, Info); Ok = ExceptionSpecificationPermitsException(E, TypeInfo, Args); @@ -385,8 +349,7 @@ } // Grab the new bad_exception... - E = UncaughtExceptionStack; - assert(E && "No uncaught exceptions!"); + E = __llvm_eh_get_uncaught_exception(); // If it's permitted, allow it to be thrown instead. va_start(Args, Info); From lattner at cs.uiuc.edu Sat Aug 30 18:19:08 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 18:19:08 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h Message-ID: <200308302318.SAA03683@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: SJLJ-Exception.h updated: 1.2 -> 1.3 --- Log message: we don't need this here --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h diff -u llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h:1.2 llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h:1.3 --- llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h:1.2 Sat Aug 30 17:47:59 2003 +++ llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h Sat Aug 30 18:18:07 2003 @@ -9,7 +9,6 @@ #define SJLJ_EXCEPTION_H #include "Exception.h" -#include struct llvm_sjlj_exception { // JmpBuffer - This is the buffer which was longjmp'd with. From lattner at cs.uiuc.edu Sat Aug 30 18:30:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 18:30:01 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/Exception.h Message-ID: <200308302329.SAA04050@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: Exception.h updated: 1.6 -> 1.7 --- Log message: Rename LongJmpException -> SJLJException --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/Exception.h diff -u llvm/runtime/GCCLibraries/libexception/Exception.h:1.6 llvm/runtime/GCCLibraries/libexception/Exception.h:1.7 --- llvm/runtime/GCCLibraries/libexception/Exception.h:1.6 Sat Aug 30 18:17:51 2003 +++ llvm/runtime/GCCLibraries/libexception/Exception.h Sat Aug 30 18:29:08 2003 @@ -42,9 +42,9 @@ }; enum { - ErrorException = 0, - LongjmpException = 1, - CXXException = 2, + ErrorException = 0, + SJLJException = 1, + CXXException = 2, }; // Language independent exception handling API... From lattner at cs.uiuc.edu Sat Aug 30 18:30:08 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 18:30:08 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.cpp Message-ID: <200308302329.SAA04045@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: SJLJ-Exception.cpp added (r1.1) --- Log message: initial checkin of SJLJ exception handling runtime --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.cpp diff -c /dev/null llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.cpp:1.1 *** /dev/null Sat Aug 30 18:29:32 2003 --- llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.cpp Sat Aug 30 18:29:22 2003 *************** *** 0 **** --- 1,123 ---- + + #include "SJLJ-Exception.h" + #include + #include + + inline llvm_sjlj_exception *get_sjlj_exception(llvm_exception *E) { + assert(E->ExceptionType == SJLJException); + return (llvm_sjlj_exception*)(E+1) - 1; + } + + // SetJmpMapEntry - One entry in a linked list of setjmps for the current + // function. + struct SetJmpMapEntry { + void *JmpBuf; + unsigned SetJmpID; + SetJmpMapEntry *Next; + }; + + static void SJLJDestructor(llvm_exception *E) { + free(get_sjlj_exception(E)); + } + + + // __llvm_sjljeh_throw_longjmp - This function creates the longjmp exception and + // returns. It takes care of mapping the longjmp value from 0 -> 1 as + // appropriate. The caller should immediately call llvm.unwind after this + // function call. + void __llvm_sjljeh_throw_longjmp(void *JmpBuffer, int Val) throw() { + llvm_sjlj_exception *E = + (llvm_sjlj_exception *)malloc(sizeof(llvm_sjlj_exception)); + E->BaseException.ExceptionDestructor = SJLJDestructor; + E->BaseException.ExceptionType = SJLJException; + E->BaseException.HandlerCount = 0; + E->BaseException.isRethrown = 0; + E->JmpBuffer = JmpBuffer; + E->LongJmpValue = Val ? Val : 1; + + __llvm_eh_add_uncaught_exception(&E->BaseException); + } + + // __llvm_sjljeh_init_setjmpmap - This funciton initializes the pointer provided + // to an empty setjmp map, and should be called on entry to a function which + // calls setjmp. + void __llvm_sjljeh_init_setjmpmap(void **SetJmpMap) throw() { + *SetJmpMap = 0; + } + + // __llvm_sjljeh_destroy_setjmpmap - This function frees all memory associated + // with the specified setjmpmap structure. It should be called on all exits + // (returns or unwinds) from the function which calls ...init_setjmpmap. + void __llvm_sjljeh_destroy_setjmpmap(void **SetJmpMap) throw() { + SetJmpMapEntry *Next; + for (SetJmpMapEntry *SJE = *(SetJmpMapEntry**)SetJmpMap; SJE; SJE = Next) { + Next = SJE->Next; + free(SJE); + } + } + + // __llvm_sjljeh_add_setjmp_to_map - This function adds or updates an entry to + // the map, to indicate which setjmp should be returned to if a longjmp happens. + void __llvm_sjljeh_add_setjmp_to_map(void **SetJmpMap, void *JmpBuf, + unsigned SetJmpID) throw() { + SetJmpMapEntry **SJE = (SetJmpMapEntry**)SetJmpMap; + + // Scan for a pre-existing entry... + for (; *SJE; SJE = &(*SJE)->Next) + if ((*SJE)->JmpBuf == JmpBuf) { + (*SJE)->SetJmpID = SetJmpID; + return; + } + + // No prexisting entry found, append to the end of the list... + SetJmpMapEntry *New = (SetJmpMapEntry *)malloc(sizeof(SetJmpMapEntry)); + *SJE = New; + New->JmpBuf = JmpBuf; + New->SetJmpID = SetJmpID; + New->Next = 0; + } + + // __llvm_sjljeh_is_longjmp_exception - This function returns true if the + // current uncaught exception is a longjmp exception. This is the first step of + // catching a sjlj exception. + bool __llvm_sjljeh_is_longjmp_exception() throw() { + return __llvm_eh_current_uncaught_exception_type(SJLJException) != 0; + } + + // __llvm_sjljeh_get_longjmp_value - This function returns the value that the + // setjmp call should "return". This requires that the current uncaught + // exception be a sjlj exception, though it does not require the exception to be + // caught by this function. + int __llvm_sjljeh_get_longjmp_value() throw() { + llvm_sjlj_exception *E = + get_sjlj_exception(__llvm_eh_get_uncaught_exception()); + return E->LongJmpValue; + } + + // __llvm_sjljeh_try_catching_longjmp_exception - This function checks to see if + // the current uncaught longjmp exception matches any of the setjmps collected + // in the setjmpmap structure. If so, it catches and destroys the exception, + // returning the index of the setjmp which caught the exception. If not, it + // leaves the exception uncaught and returns a value of ~0. + unsigned __llvm_sjljeh_try_catching_longjmp_exception(void **SetJmpMap) throw(){ + llvm_sjlj_exception *E = + get_sjlj_exception(__llvm_eh_get_uncaught_exception()); + + // Scan for a matching entry in the SetJmpMap... + SetJmpMapEntry *SJE = *(SetJmpMapEntry**)SetJmpMap; + for (; SJE; SJE = SJE->Next) + if (SJE->JmpBuf == E->JmpBuffer) { + // "Catch" and destroy the exception... + __llvm_eh_pop_from_uncaught_stack(); + + // We know it's a longjmp exception, so we can just free it instead of + // calling the destructor. + free(E); + + // Return the setjmp ID which we should branch to... + return SJE->SetJmpID; + } + + // No setjmp in this function catches the exception! + return ~0; + } From lattner at cs.uiuc.edu Sat Aug 30 18:32:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 18:32:02 2003 Subject: [llvm-commits] CVS: llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.cpp Message-ID: <200308302331.SAA04170@apoc.cs.uiuc.edu> Changes in directory llvm/runtime/GCCLibraries/libexception: SJLJ-Exception.cpp updated: 1.1 -> 1.2 --- Log message: Urg, forgot to add a file header somehow. Add missing function comments --- Diffs of the changes: Index: llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.cpp diff -u llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.cpp:1.1 llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.cpp:1.2 --- llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.cpp:1.1 Sat Aug 30 18:29:22 2003 +++ llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.cpp Sat Aug 30 18:31:08 2003 @@ -1,8 +1,16 @@ +//===- SJLJ-Exception.cpp - SetJmp/LongJmp Exception Handling -------------===// +// +// This file implements the API used by the Setjmp/Longjmp exception handling +// runtime library. +// +//===----------------------------------------------------------------------===// #include "SJLJ-Exception.h" #include #include +// get_sjlj_exception - Adjust the llvm_exception pointer to be an appropriate +// llvm_sjlj_exception pointer. inline llvm_sjlj_exception *get_sjlj_exception(llvm_exception *E) { assert(E->ExceptionType == SJLJException); return (llvm_sjlj_exception*)(E+1) - 1; @@ -16,6 +24,9 @@ SetJmpMapEntry *Next; }; +// SJLJDestructor - This function is used to free the exception when +// language-indent code needs to destroy the exception without knowing exactly +// what type it is. static void SJLJDestructor(llvm_exception *E) { free(get_sjlj_exception(E)); } From lattner at cs.uiuc.edu Sat Aug 30 19:20:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 19:20:01 2003 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Module.cpp Message-ID: <200308310019.TAA11111@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Module.cpp updated: 1.38 -> 1.39 --- Log message: Implement new method --- Diffs of the changes: Index: llvm/lib/VMCore/Module.cpp diff -u llvm/lib/VMCore/Module.cpp:1.38 llvm/lib/VMCore/Module.cpp:1.39 --- llvm/lib/VMCore/Module.cpp:1.38 Sun Aug 24 08:48:48 2003 +++ llvm/lib/VMCore/Module.cpp Sat Aug 30 19:19:28 2003 @@ -12,6 +12,7 @@ #include "Support/LeakDetector.h" #include "SymbolTableListTraitsImpl.h" #include +#include #include Function *ilist_traits::createNode() { @@ -94,6 +95,29 @@ return New; // Return the new prototype... } } + +// getOrInsertFunction - Look up the specified function in the module symbol +// table. If it does not exist, add a prototype for the function and return it. +// This version of the method takes a null terminated list of function +// arguments, which makes it easier for clients to use. +// +Function *Module::getOrInsertFunction(const std::string &Name, + const Type *RetTy, ...) { + va_list Args; + va_start(Args, RetTy); + + // Build the list of argument types... + std::vector ArgTys; + while (const Type *ArgTy = va_arg(Args, const Type*)) + ArgTys.push_back(ArgTy); + + va_end(Args); + + // Build the function type and chain to the other getOrInsertFunction... + return getOrInsertFunction(Name, FunctionType::get(RetTy, ArgTys, false)); +} + + // getFunction - Look up the specified function in the module symbol table. // If it does not exist, return null. From lattner at cs.uiuc.edu Sat Aug 30 19:20:08 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 19:20:08 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Module.h Message-ID: <200308310019.TAA11102@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Module.h updated: 1.33 -> 1.34 --- Log message: Add new helper function which makes it even easier to do this sort of thing --- Diffs of the changes: Index: llvm/include/llvm/Module.h diff -u llvm/include/llvm/Module.h:1.33 llvm/include/llvm/Module.h:1.34 --- llvm/include/llvm/Module.h:1.33 Sun Aug 24 08:46:37 2003 +++ llvm/include/llvm/Module.h Sat Aug 30 19:19:18 2003 @@ -90,6 +90,12 @@ /// it. Function *getOrInsertFunction(const std::string &Name, const FunctionType *T); + /// getOrInsertFunction - Look up the specified function in the module symbol + /// table. If it does not exist, add a prototype for the function and return + /// it. This version of the method takes a null terminated list of function + /// arguments, which makes it easier for clients to use. + Function *getOrInsertFunction(const std::string &Name, const Type *RetTy,...); + /// getFunction - Look up the specified function in the module symbol table. /// If it does not exist, return null. /// From lattner at cs.uiuc.edu Sat Aug 30 19:21:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 19:21:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Instrumentation/TraceValues.cpp Message-ID: <200308310020.TAA11363@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Instrumentation: TraceValues.cpp updated: 1.58 -> 1.59 --- Log message: Use the new interface, simplifies code --- Diffs of the changes: Index: llvm/lib/Transforms/Instrumentation/TraceValues.cpp diff -u llvm/lib/Transforms/Instrumentation/TraceValues.cpp:1.58 llvm/lib/Transforms/Instrumentation/TraceValues.cpp:1.59 --- llvm/lib/Transforms/Instrumentation/TraceValues.cpp:1.58 Fri Jul 11 16:57:43 2003 +++ llvm/lib/Transforms/Instrumentation/TraceValues.cpp Sat Aug 30 19:20:36 2003 @@ -120,23 +120,18 @@ PrintfFunc = M.getOrInsertFunction("printf", MTy); // uint (sbyte*) - const FunctionType *hashFuncTy = - FunctionType::get(Type::UIntTy, vector(1, SBP), false); - HashPtrFunc = M.getOrInsertFunction("HashPointerToSeqNum", hashFuncTy); + HashPtrFunc = M.getOrInsertFunction("HashPointerToSeqNum", Type::UIntTy, SBP, + 0); // void (sbyte*) - const FunctionType *voidSBPFuncTy = - FunctionType::get(Type::VoidTy, vector(1, SBP), false); + ReleasePtrFunc = M.getOrInsertFunction("ReleasePointerSeqNum", + Type::VoidTy, SBP, 0); + RecordPtrFunc = M.getOrInsertFunction("RecordPointer", + Type::VoidTy, SBP, 0); - ReleasePtrFunc = M.getOrInsertFunction("ReleasePointerSeqNum", voidSBPFuncTy); - RecordPtrFunc = M.getOrInsertFunction("RecordPointer", voidSBPFuncTy); - - const FunctionType *voidvoidFuncTy = - FunctionType::get(Type::VoidTy, vector(), false); - - PushOnEntryFunc = M.getOrInsertFunction("PushPointerSet", voidvoidFuncTy); + PushOnEntryFunc = M.getOrInsertFunction("PushPointerSet", Type::VoidTy, 0); ReleaseOnReturnFunc = M.getOrInsertFunction("ReleasePointersPopSet", - voidvoidFuncTy); + Type::VoidTy, 0); } From lattner at cs.uiuc.edu Sat Aug 30 19:22:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 19:22:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp Message-ID: <200308310021.TAA11625@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Instrumentation/ProfilePaths: EdgeCode.cpp updated: 1.22 -> 1.23 --- Log message: Use the new interface, simplifies code Delete a bunch of commented out code --- Diffs of the changes: Index: llvm/lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp diff -u llvm/lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp:1.22 llvm/lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp:1.23 --- llvm/lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp:1.22 Mon Jun 30 16:58:52 2003 +++ llvm/lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp Sat Aug 30 19:21:05 2003 @@ -27,22 +27,16 @@ static void getTriggerCode(Module *M, BasicBlock *BB, int MethNo, Value *pathNo, Value *cnt, Instruction *rInst){ - vector args; - //args.push_back(PointerType::get(Type::SByteTy)); - args.push_back(Type::IntTy); - args.push_back(Type::IntTy); - //args.push_back(Type::IntTy); - args.push_back(PointerType::get(Type::IntTy)); - args.push_back(PointerType::get(Type::IntTy)); - const FunctionType *MTy = FunctionType::get(Type::VoidTy, args, false); - vector tmpVec; tmpVec.push_back(Constant::getNullValue(Type::LongTy)); tmpVec.push_back(Constant::getNullValue(Type::LongTy)); Instruction *Idx = new GetElementPtrInst(cnt, tmpVec, "");//, BB->getInstList().push_back(Idx); - Function *trigMeth = M->getOrInsertFunction("trigger", MTy); + const Type *PIntTy = PointerType::get(Type::IntTy); + Function *trigMeth = M->getOrInsertFunction("trigger", Type::VoidTy, + Type::IntTy, Type::IntTy, + PIntTy, PIntTy, 0); assert(trigMeth && "trigger method could not be inserted!"); vector trargs; @@ -277,39 +271,6 @@ //store uint 0, uint *%R new StoreInst(Int0, rVar, here); - - //insert initialize function for initializing - //vector inCountArgs; - //inCountArgs.push_back(PointerType::get(Type::IntTy)); - //inCountArgs.push_back(Type::IntTy); - - //const FunctionType *cFty = FunctionType::get(Type::VoidTy, inCountArgs, - // false); -//Function *inCountMth = front->getParent()->getParent()->getOrInsertFunction("llvmInitializeCounter", cFty); -//assert(inCountMth && "Initialize method could not be inserted!"); - -//vector iniArgs; -//iniArgs.push_back(countVar); -//iniArgs.push_back(ConstantSInt::get(Type::IntTy, k)); -//new CallInst(inCountMth, iniArgs, "", here); - -/* - if(front->getParent()->getName() == "main"){ - //intialize threshold - vector initialize_args; - initialize_args.push_back(PointerType::get(Type::IntTy)); - - const FunctionType *Fty = FunctionType::get(Type::VoidTy, initialize_args, - false); - Function *initialMeth = front->getParent()->getParent()->getOrInsertFunction("reoptimizerInitialize", Fty); - assert(initialMeth && "Initialize method could not be inserted!"); - - vector trargs; - trargs.push_back(threshold); - - new CallInst(initialMeth, trargs, "", here); - } -*/ } From lattner at cs.uiuc.edu Sat Aug 30 19:23:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 19:23:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LowerAllocations.cpp Message-ID: <200308310022.TAA11908@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LowerAllocations.cpp updated: 1.39 -> 1.40 --- Log message: Use new interface, simplifies code --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/LowerAllocations.cpp diff -u llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.39 llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.40 --- llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.39 Thu Aug 21 17:12:22 2003 +++ llvm/lib/Transforms/Scalar/LowerAllocations.cpp Sat Aug 30 19:22:27 2003 @@ -58,17 +58,9 @@ // This function is always successful. // bool LowerAllocations::doInitialization(Module &M) { - const FunctionType *MallocType = - FunctionType::get(PointerType::get(Type::SByteTy), - std::vector(1, Type::UIntTy), false); - const FunctionType *FreeType = - FunctionType::get(Type::VoidTy, - std::vector(1, - PointerType::get(Type::SByteTy)), - false); - - MallocFunc = M.getOrInsertFunction("malloc", MallocType); - FreeFunc = M.getOrInsertFunction("free" , FreeType); + const Type *SBPTy = PointerType::get(Type::SByteTy); + MallocFunc = M.getOrInsertFunction("malloc", SBPTy, Type::UIntTy, 0); + FreeFunc = M.getOrInsertFunction("free" , Type::VoidTy, SBPTy, 0); return true; } From lattner at cs.uiuc.edu Sat Aug 30 19:23:07 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 19:23:07 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Instrumentation/ProfilePaths/InstLoops.cpp ProfilePaths.cpp Message-ID: <200308310022.TAA11757@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Instrumentation/ProfilePaths: InstLoops.cpp updated: 1.5 -> 1.6 ProfilePaths.cpp updated: 1.29 -> 1.30 --- Log message: Use the new interface, simplifies code NOTE that these two files are _BUGGY_ and need to be fixed, just not by me :) --- Diffs of the changes: Index: llvm/lib/Transforms/Instrumentation/ProfilePaths/InstLoops.cpp diff -u llvm/lib/Transforms/Instrumentation/ProfilePaths/InstLoops.cpp:1.5 llvm/lib/Transforms/Instrumentation/ProfilePaths/InstLoops.cpp:1.6 --- llvm/lib/Transforms/Instrumentation/ProfilePaths/InstLoops.cpp:1.5 Tue Aug 12 17:00:24 2003 +++ llvm/lib/Transforms/Instrumentation/ProfilePaths/InstLoops.cpp Sat Aug 30 19:21:59 2003 @@ -121,6 +121,12 @@ removeRedundant(be); + // FIXME: THIS IS HORRIBLY BROKEN. FunctionPass's cannot do this, except in + // their initialize function!! + Function *inCountMth = + F.getParent()->getOrInsertFunction("llvm_first_trigger", + Type::VoidTy, 0); + for(std::map::iterator MI = be.begin(), ME = be.end(); MI != ME; ++MI){ BasicBlock *u = MI->first; @@ -137,15 +143,6 @@ ti->setSuccessor(index, newBB); BasicBlock::InstListType < = newBB->getInstList(); - - std::vector inCountArgs; - const FunctionType *cFty = FunctionType::get(Type::VoidTy, inCountArgs, - false); - Function *inCountMth = - u->getParent()->getParent()->getOrInsertFunction("llvm_first_trigger", - cFty); - - assert(inCountMth && "Initial method could not be inserted!"); Instruction *call = new CallInst(inCountMth); lt.push_back(call); Index: llvm/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp diff -u llvm/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp:1.29 llvm/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp:1.30 --- llvm/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp:1.29 Mon Jun 30 16:58:52 2003 +++ llvm/lib/Transforms/Instrumentation/ProfilePaths/ProfilePaths.cpp Sat Aug 30 19:21:59 2003 @@ -176,18 +176,16 @@ if(fr->getParent()->getName() == "main"){ //intialize threshold - vector initialize_args; - initialize_args.push_back(PointerType::get(Type::IntTy)); - - const FunctionType *Fty = FunctionType::get(Type::VoidTy, initialize_args, - false); - Function *initialMeth = fr->getParent()->getParent()->getOrInsertFunction("reoptimizerInitialize", Fty); - assert(initialMeth && "Initialize method could not be inserted!"); + + // FIXME: THIS IS HORRIBLY BROKEN. FUNCTION PASSES CANNOT DO THIS, EXCEPT + // IN THEIR INITIALIZE METHOD!! + Function *initialize = + F.getParent()->getOrInsertFunction("reoptimizerInitialize", Type::VoidTy, + PointerType::get(Type::IntTy), 0); vector trargs; trargs.push_back(threshold); - - new CallInst(initialMeth, trargs, "", fr->begin()); + new CallInst(initialize, trargs, "", fr->begin()); } From lattner at cs.uiuc.edu Sat Aug 30 19:46:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 19:46:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp Message-ID: <200308310045.TAA16587@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: ScalarReplAggregates.cpp updated: 1.8 -> 1.9 --- Log message: ScalarRepl does not modify the CFG. Say so! --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp diff -u llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.8 llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.9 --- llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.8 Fri Aug 1 17:15:03 2003 +++ llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp Sat Aug 30 19:45:13 2003 @@ -23,6 +23,12 @@ struct SROA : public FunctionPass { bool runOnFunction(Function &F); + // getAnalysisUsage - This pass does not require any passes, but we know it + // will not alter the CFG, so say so. + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesCFG(); + } + private: bool isSafeElementUse(Value *Ptr); bool isSafeUseOfAllocation(Instruction *User); From lattner at cs.uiuc.edu Sat Aug 30 20:39:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 20:39:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/CallGraph.h Message-ID: <200308310138.UAA18111@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: CallGraph.h updated: 1.28 -> 1.29 --- Log message: s/Meth/F --- Diffs of the changes: Index: llvm/include/llvm/Analysis/CallGraph.h diff -u llvm/include/llvm/Analysis/CallGraph.h:1.28 llvm/include/llvm/Analysis/CallGraph.h:1.29 --- llvm/include/llvm/Analysis/CallGraph.h:1.28 Sat Jun 21 22:05:45 2003 +++ llvm/include/llvm/Analysis/CallGraph.h Sat Aug 30 20:38:00 2003 @@ -104,7 +104,7 @@ // Functions to keep a call graph up to date with a function that has been // modified // - void addFunctionToModule(Function *Meth); + void addFunctionToModule(Function *F); // removeFunctionFromModule - Unlink the function from this module, returning @@ -114,8 +114,8 @@ // is to dropAllReferences before calling this. // Function *removeFunctionFromModule(CallGraphNode *CGN); - Function *removeFunctionFromModule(Function *Meth) { - return removeFunctionFromModule((*this)[Meth]); + Function *removeFunctionFromModule(Function *F) { + return removeFunctionFromModule((*this)[F]); } @@ -168,7 +168,7 @@ // CallGraphNode class definition // class CallGraphNode { - Function *Meth; + Function *F; std::vector CalledFunctions; CallGraphNode(const CallGraphNode &); // Do not implement @@ -181,7 +181,7 @@ typedef std::vector::const_iterator const_iterator; // getFunction - Return the function that this call graph node represents... - Function *getFunction() const { return Meth; } + Function *getFunction() const { return F; } inline iterator begin() { return CalledFunctions.begin(); } inline iterator end() { return CalledFunctions.end(); } @@ -207,7 +207,7 @@ friend class CallGraph; // CallGraphNode ctor - Create a node for the specified function... - inline CallGraphNode(Function *F) : Meth(F) {} + inline CallGraphNode(Function *f) : F(f) {} // addCalledFunction add a function to the list of functions called by this // one From lattner at cs.uiuc.edu Sat Aug 30 20:46:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 20:46:02 2003 Subject: [llvm-commits] CVS: llvm/include/Support/TarjanSCCIterator.h Message-ID: <200308310145.UAA18780@apoc.cs.uiuc.edu> Changes in directory llvm/include/Support: TarjanSCCIterator.h updated: 1.9 -> 1.10 --- Log message: This file uses cerr without including . Since it's just for debugging, comment it out --- Diffs of the changes: Index: llvm/include/Support/TarjanSCCIterator.h diff -u llvm/include/Support/TarjanSCCIterator.h:1.9 llvm/include/Support/TarjanSCCIterator.h:1.10 --- llvm/include/Support/TarjanSCCIterator.h:1.9 Fri Aug 1 17:12:07 2003 +++ llvm/include/Support/TarjanSCCIterator.h Sat Aug 30 20:45:00 2003 @@ -94,8 +94,8 @@ SCCNodeStack.push(N); MinVisitNumStack.push(visitNum); VisitStack.push(make_pair(N, GT::child_begin(N))); - DEBUG(std::cerr << "TarjanSCC: Node " << N << - " : visitNum = " << visitNum << "\n"); + //DEBUG(std::cerr << "TarjanSCC: Node " << N << + // " : visitNum = " << visitNum << "\n"); } // The stack-based DFS traversal; defined below. @@ -133,9 +133,9 @@ if (! MinVisitNumStack.empty() && MinVisitNumStack.top() > minVisitNum) MinVisitNumStack.top() = minVisitNum; - DEBUG(std::cerr << "TarjanSCC: Popped node " << visitingN << - " : minVisitNum = " << minVisitNum << "; Node visit num = " << - nodeVisitNumbers[visitingN] << "\n"); + //DEBUG(std::cerr << "TarjanSCC: Popped node " << visitingN << + // " : minVisitNum = " << minVisitNum << "; Node visit num = " << + // nodeVisitNumbers[visitingN] << "\n"); if (minVisitNum == nodeVisitNumbers[visitingN]) { // A full SCC is on the SCCNodeStack! It includes all nodes below From lattner at cs.uiuc.edu Sat Aug 30 20:49:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 20:49:00 2003 Subject: [llvm-commits] CVS: llvm/include/Support/TarjanSCCIterator.h Message-ID: <200308310148.UAA19317@apoc.cs.uiuc.edu> Changes in directory llvm/include/Support: TarjanSCCIterator.h updated: 1.10 -> 1.11 --- Log message: Remove usage of unsigned long: unsigned should be enough! Remove explicit use of a stack<>, use a vector instead --- Diffs of the changes: Index: llvm/include/Support/TarjanSCCIterator.h diff -u llvm/include/Support/TarjanSCCIterator.h:1.10 llvm/include/Support/TarjanSCCIterator.h:1.11 --- llvm/include/Support/TarjanSCCIterator.h:1.10 Sat Aug 30 20:45:00 2003 +++ llvm/include/Support/TarjanSCCIterator.h Sat Aug 30 20:48:21 2003 @@ -19,7 +19,6 @@ #include "Support/Debug.h" #include "Support/iterator" #include -#include #include //-------------------------------------------------------------------------- @@ -69,31 +68,31 @@ // The visit counters used to detect when a complete SCC is on the stack. // visitNum is the global counter. // nodeVisitNumbers are per-node visit numbers, also used as DFS flags. - unsigned long visitNum; - std::map nodeVisitNumbers; + unsigned visitNum; + std::map nodeVisitNumbers; // SCCNodeStack - Stack holding nodes of the SCC. - std::stack SCCNodeStack; + std::vector SCCNodeStack; // CurrentSCC - The current SCC, retrieved using operator*(). SccTy CurrentSCC; // VisitStack - Used to maintain the ordering. Top = current block // First element is basic block pointer, second is the 'next child' to visit - std::stack > VisitStack; + std::vector > VisitStack; // MinVistNumStack - Stack holding the "min" values for each node in the DFS. // This is used to track the minimum uplink values for all children of // the corresponding node on the VisitStack. - std::stack MinVisitNumStack; + std::vector MinVisitNumStack; // A single "visit" within the non-recursive DFS traversal. void DFSVisitOne(NodeType* N) { ++visitNum; // Global counter for the visit order nodeVisitNumbers[N] = visitNum; - SCCNodeStack.push(N); - MinVisitNumStack.push(visitNum); - VisitStack.push(make_pair(N, GT::child_begin(N))); + SCCNodeStack.push_back(N); + MinVisitNumStack.push_back(visitNum); + VisitStack.push_back(make_pair(N, GT::child_begin(N))); //DEBUG(std::cerr << "TarjanSCC: Node " << N << // " : visitNum = " << visitNum << "\n"); } @@ -101,18 +100,18 @@ // The stack-based DFS traversal; defined below. void DFSVisitChildren() { assert(!VisitStack.empty()); - while (VisitStack.top().second != GT::child_end(VisitStack.top().first)) + while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) { // TOS has at least one more child so continue DFS - NodeType *childN = *VisitStack.top().second++; + NodeType *childN = *VisitStack.back().second++; if (nodeVisitNumbers.find(childN) == nodeVisitNumbers.end()) { // this node has never been seen DFSVisitOne(childN); } else { - unsigned long childNum = nodeVisitNumbers[childN]; - if (MinVisitNumStack.top() > childNum) - MinVisitNumStack.top() = childNum; + unsigned childNum = nodeVisitNumbers[childN]; + if (MinVisitNumStack.back() > childNum) + MinVisitNumStack.back() = childNum; } } } @@ -125,13 +124,14 @@ { DFSVisitChildren(); - assert(VisitStack.top().second==GT::child_end(VisitStack.top().first)); - NodeType* visitingN = VisitStack.top().first; - unsigned long minVisitNum = MinVisitNumStack.top(); - VisitStack.pop(); - MinVisitNumStack.pop(); - if (! MinVisitNumStack.empty() && MinVisitNumStack.top() > minVisitNum) - MinVisitNumStack.top() = minVisitNum; + assert(VisitStack.back().second == + GT::child_end(VisitStack.back().first)); + NodeType* visitingN = VisitStack.back().first; + unsigned minVisitNum = MinVisitNumStack.back(); + VisitStack.pop_back(); + MinVisitNumStack.pop_back(); + if (! MinVisitNumStack.empty() && MinVisitNumStack.back() > minVisitNum) + MinVisitNumStack.back() = minVisitNum; //DEBUG(std::cerr << "TarjanSCC: Popped node " << visitingN << // " : minVisitNum = " << minVisitNum << "; Node visit num = " << @@ -143,8 +143,8 @@ // reset their minVisit values, and return (this suspends // the DFS traversal till the next ++). do { - CurrentSCC.push_back(SCCNodeStack.top()); - SCCNodeStack.pop(); + CurrentSCC.push_back(SCCNodeStack.back()); + SCCNodeStack.pop_back(); nodeVisitNumbers[CurrentSCC.back()] = ~0UL; } while (CurrentSCC.back() != visitingN); return; From lattner at cs.uiuc.edu Sat Aug 30 20:56:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 20:56:03 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/CallGraphSCCPass.h Message-ID: <200308310155.UAA19954@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: CallGraphSCCPass.h added (r1.1) --- Log message: Initial checkin of the CallGraphSCCPass class --- Diffs of the changes: Index: llvm/include/llvm/CallGraphSCCPass.h diff -c /dev/null llvm/include/llvm/CallGraphSCCPass.h:1.1 *** /dev/null Sat Aug 30 20:55:09 2003 --- llvm/include/llvm/CallGraphSCCPass.h Sat Aug 30 20:54:59 2003 *************** *** 0 **** --- 1,42 ---- + //===- CallGraphSCCPass.h - Pass that operates BU on call graph -*- C++ -*-===// + // + // This file defines the CallGraphSCCPass class, which is used for passes which + // are implemented as bottom-up traversals on the call graph. Because there may + // be cycles in the call graph, passes of this type operate on the call-graph in + // SCC order: that is, they process function bottom-up, except for recursive + // functions, which they process all at once. + // + // These passes are inherently interprocedural, and are required to keep the + // call graph up-to-date if they do anything which could modify it. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_CALL_GRAPH_SCC_PASS_H + #define LLVM_CALL_GRAPH_SCC_PASS_H + + #include "llvm/Pass.h" + + class CallGraphNode; + + struct CallGraphSCCPass : public Pass { + + /// runOnSCC - This method should be implemented by the subclass to perform + /// whatever action is necessary for the specified SCC. Note that + /// non-recursive (or only self-recursive) functions will have an SCC size of + /// 1, where recursive portions of the call graph will have SCC size > 1. + /// + virtual bool runOnSCC(const std::vector &SCC) = 0; + + /// run - Run this pass, returning true if a modification was made to the + /// module argument. This is implemented in terms of the runOnSCC method. + /// + virtual bool run(Module &M); + + + /// getAnalysisUsage - For this class, we declare that we require and preserve + /// the call graph. If the derived class implements this method, it should + /// always explicitly call the implementation here. + virtual void getAnalysisUsage(AnalysisUsage &Info) const; + }; + + #endif From lattner at cs.uiuc.edu Sat Aug 30 20:56:10 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 20:56:10 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp Message-ID: <200308310155.UAA19947@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: CallGraphSCCPass.cpp added (r1.1) --- Log message: Initial checkin of the CallGraphSCCPass class --- Diffs of the changes: Index: llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp diff -c /dev/null llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp:1.1 *** /dev/null Sat Aug 30 20:55:07 2003 --- llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp Sat Aug 30 20:54:57 2003 *************** *** 0 **** --- 1,30 ---- + //===- CallGraphSCCPass.cpp - Pass that operates BU on call graph ---------===// + // + // This file implements the CallGraphSCCPass class, which is used for passes + // which are implemented as bottom-up traversals on the call graph. Because + // there may be cycles in the call graph, passes of this type operate on the + // call-graph in SCC order: that is, they process function bottom-up, except for + // recursive functions, which they process all at once. + // + //===----------------------------------------------------------------------===// + + #include "llvm/CallGraphSCCPass.h" + #include "llvm/Analysis/CallGraph.h" + #include "Support/TarjanSCCIterator.h" + + /// getAnalysisUsage - For this class, we declare that we require and preserve + /// the call graph. If the derived class implements this method, it should + /// always explicitly call the implementation here. + void CallGraphSCCPass::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.addPreserved(); + } + + bool CallGraphSCCPass::run(Module &M) { + CallGraph &CG = getAnalysis(); + bool Changed = false; + for (TarjanSCC_iterator I = tarj_begin(&CG), E = tarj_end(&CG); + I != E; ++I) + Changed = runOnSCC(**I); + return Changed; + } From lattner at cs.uiuc.edu Sat Aug 30 21:37:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 21:37:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/Makefile Message-ID: <200308310236.VAA23304@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms: Makefile updated: 1.26 -> 1.27 --- Log message: Add tests for the pruneeh pass --- Diffs of the changes: Index: llvm/test/Regression/Transforms/Makefile diff -u llvm/test/Regression/Transforms/Makefile:1.26 llvm/test/Regression/Transforms/Makefile:1.27 --- llvm/test/Regression/Transforms/Makefile:1.26 Sat Jun 28 18:17:42 2003 +++ llvm/test/Regression/Transforms/Makefile Sat Aug 30 21:36:10 2003 @@ -12,11 +12,12 @@ InstCombine \ LevelRaise \ LICM \ + LoopPreheaders \ LowerSwitch \ Mem2Reg \ PiNodeInserter \ PRE \ - LoopPreheaders \ + PruneEH \ ProfilePaths \ Reassociate \ SCCP \ From lattner at cs.uiuc.edu Sat Aug 30 21:37:08 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 21:37:08 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/PruneEH/ Message-ID: <200308310236.VAA23294@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/PruneEH: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Regression/Transforms/PruneEH added to the repository --- Diffs of the changes: From lattner at cs.uiuc.edu Sat Aug 30 21:39:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 21:39:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/PruneEH/Makefile recursivetest.llx simpletest.llx Message-ID: <200308310238.VAA23457@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/PruneEH: Makefile added (r1.1) recursivetest.llx added (r1.1) simpletest.llx added (r1.1) --- Log message: new tests --- Diffs of the changes: Index: llvm/test/Regression/Transforms/PruneEH/Makefile diff -c /dev/null llvm/test/Regression/Transforms/PruneEH/Makefile:1.1 *** /dev/null Sat Aug 30 21:38:56 2003 --- llvm/test/Regression/Transforms/PruneEH/Makefile Sat Aug 30 21:38:46 2003 *************** *** 0 **** --- 1,10 ---- + + LEVEL = ../../../.. + include $(LEVEL)/test/Makefile.tests + + TESTS := $(wildcard *.llx) + + all:: $(addprefix Output/, $(TESTS:%.llx=%.llx.out)) + + Output/%.llx.out: %.llx Output/.dir $(LOPT) + -$(TESTRUNR) $< Index: llvm/test/Regression/Transforms/PruneEH/recursivetest.llx diff -c /dev/null llvm/test/Regression/Transforms/PruneEH/recursivetest.llx:1.1 *** /dev/null Sat Aug 30 21:38:56 2003 --- llvm/test/Regression/Transforms/PruneEH/recursivetest.llx Sat Aug 30 21:38:46 2003 *************** *** 0 **** --- 1,19 ---- + ; RUN: as < %s | opt -prune-eh | dis | not grep invoke + + implementation + + internal int %foo() { + invoke int %foo() to label %Normal except label %Except + Normal: + ret int 12 + Except: + ret int 123 + } + + int %caller() { + invoke int %foo() to label %Normal except label %Except + Normal: + ret int 0 + Except: + ret int 1 + } Index: llvm/test/Regression/Transforms/PruneEH/simpletest.llx diff -c /dev/null llvm/test/Regression/Transforms/PruneEH/simpletest.llx:1.1 *** /dev/null Sat Aug 30 21:38:56 2003 --- llvm/test/Regression/Transforms/PruneEH/simpletest.llx Sat Aug 30 21:38:46 2003 *************** *** 0 **** --- 1,15 ---- + ; RUN: as < %s | opt -prune-eh | dis | not grep invoke + + implementation + + internal void %foo() { + ret void ; does not throw + } + + int %caller() { + invoke void %foo() to label %Normal except label %Except + Normal: + ret int 0 + Except: + ret int 1 + } From lattner at cs.uiuc.edu Sat Aug 30 21:48:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 21:48:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/PruneEH.cpp Message-ID: <200308310247.VAA24356@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: PruneEH.cpp added (r1.1) --- Log message: Initial checkin of the -prune-eh pass, a very simple exception handling removal pass --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/PruneEH.cpp diff -c /dev/null llvm/lib/Transforms/IPO/PruneEH.cpp:1.1 *** /dev/null Sat Aug 30 21:47:43 2003 --- llvm/lib/Transforms/IPO/PruneEH.cpp Sat Aug 30 21:47:32 2003 *************** *** 0 **** --- 1,93 ---- + //===- PruneEH.cpp - Pass which deletes unused exception handlers ---------===// + // + // This file implements a simple interprocedural pass which walks the + // call-graph, turning invoke instructions into calls, iff the callee cannot + // throw an exception. It implements this as a bottom-up traversal of the + // call-graph. + // + //===----------------------------------------------------------------------===// + + #include "llvm/CallGraphSCCPass.h" + #include "llvm/Function.h" + #include "llvm/Intrinsics.h" + #include "llvm/iTerminators.h" + #include "llvm/iOther.h" + #include "llvm/Analysis/CallGraph.h" + #include "Support/Statistic.h" + #include + + namespace { + Statistic<> NumRemoved("prune-eh", "Number of invokes removed"); + + struct PruneEH : public CallGraphSCCPass { + /// DoesNotThrow - This set contains all of the functions which we have + /// determined cannot throw exceptions. + std::set DoesNotThrow; + + // runOnSCC - Analyze the SCC, performing the transformation if possible. + bool runOnSCC(const std::vector &SCC); + }; + RegisterOpt X("prune-eh", "Remove unused exception handling info"); + } + + + bool PruneEH::runOnSCC(const std::vector &SCC) { + CallGraph &CG = getAnalysis(); + + // First, check to see if any callees might throw or if there are any external + // functions in this SCC: if so, we cannot prune any functions in this SCC. + // If this SCC includes the llvm.unwind intrinsic, we KNOW it throws, so + // obviously the SCC might throw. + // + bool SCCMightThrow = false; + for (unsigned i = 0, e = SCC.size(); i != e; ++i) + if (!DoesNotThrow.count(SCC[i]) && // Calls maybe throwing fn + // Make sure this is not one of the fn's in the SCC. + std::find(SCC.begin(), SCC.end(), SCC[i]) == SCC.end()) { + SCCMightThrow = true; break; + } else if (Function *F = SCC[i]->getFunction()) + if (F->isExternal() || // Is external function + F->getIntrinsicID() == LLVMIntrinsic::unwind) {// Is unwind function! + SCCMightThrow = true; break; + } + + bool MadeChange = false; + + for (unsigned i = 0, e = SCC.size(); i != e; ++i) { + // If the SCC can't throw, remember this for callers... + if (!SCCMightThrow) + DoesNotThrow.insert(SCC[i]); + + // Convert any invoke instructions to non-throwing functions in this node + // into call instructions with a branch. This makes the exception blocks + // dead. + if (Function *F = SCC[i]->getFunction()) + for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) + if (InvokeInst *II = dyn_cast(I->getTerminator())) + if (Function *F = II->getCalledFunction()) + if (DoesNotThrow.count(CG[F])) { + // Insert a call instruction before the invoke... + std::string Name = II->getName(); II->setName(""); + Value *Call = new CallInst(II->getCalledValue(), + std::vector(II->op_begin()+3, + II->op_end()), + Name, II); + + // Anything that used the value produced by the invoke instruction + // now uses the value produced by the call instruction. + II->replaceAllUsesWith(Call); + + // Insert a branch to the normal destination right before the + // invoke. + new BranchInst(II->getNormalDest(), II); + + // Finally, delete the invoke instruction! + I->getInstList().pop_back(); + + ++NumRemoved; + MadeChange = true; + } + } + + return MadeChange; + } From lattner at cs.uiuc.edu Sat Aug 30 21:51:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Aug 30 21:51:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/BasicBlock.h Message-ID: <200308310250.VAA24379@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: BasicBlock.h updated: 1.29 -> 1.30 --- Log message: Minor simplification --- Diffs of the changes: Index: llvm/include/llvm/BasicBlock.h diff -u llvm/include/llvm/BasicBlock.h:1.29 llvm/include/llvm/BasicBlock.h:1.30 --- llvm/include/llvm/BasicBlock.h:1.29 Sat Aug 23 22:41:37 2003 +++ llvm/include/llvm/BasicBlock.h Sat Aug 30 21:50:07 2003 @@ -37,8 +37,7 @@ static iplist &getList(BasicBlock *BB); }; -class BasicBlock : public Value { // Basic blocks are data objects also -public: +struct BasicBlock : public Value { // Basic blocks are data objects also typedef iplist InstListType; private : InstListType InstList; From lattner at cs.uiuc.edu Sun Aug 31 01:54:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 01:54:00 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/CompileFail/2003-08-31-StructLayout.cpp Message-ID: <200308310653.BAA28769@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend/CompileFail: 2003-08-31-StructLayout.cpp added (r1.1) --- Log message: New testcase for annoying structure layout stuff! --- Diffs of the changes: Index: llvm/test/Regression/C++Frontend/CompileFail/2003-08-31-StructLayout.cpp diff -c /dev/null llvm/test/Regression/C++Frontend/CompileFail/2003-08-31-StructLayout.cpp:1.1 *** /dev/null Sun Aug 31 01:53:15 2003 --- llvm/test/Regression/C++Frontend/CompileFail/2003-08-31-StructLayout.cpp Sun Aug 31 01:53:05 2003 *************** *** 0 **** --- 1,14 ---- + // There is a HOLE in the derived2 object due to not wanting to place the two + // baseclass instances at the same offset! + + struct baseclass {}; + + class derived1 : public baseclass { + void * NodePtr; + }; + + class derived2 : public baseclass { + derived1 current; + }; + + derived2 RI; From lattner at cs.uiuc.edu Sun Aug 31 11:31:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 11:31:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/IPO.h Message-ID: <200308311630.LAA10313@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: IPO.h updated: 1.18 -> 1.19 --- Log message: Add accessor function for the PruneEH pass --- Diffs of the changes: Index: llvm/include/llvm/Transforms/IPO.h diff -u llvm/include/llvm/Transforms/IPO.h:1.18 llvm/include/llvm/Transforms/IPO.h:1.19 --- llvm/include/llvm/Transforms/IPO.h:1.18 Tue Jun 24 23:12:29 2003 +++ llvm/include/llvm/Transforms/IPO.h Sun Aug 31 11:30:25 2003 @@ -62,6 +62,12 @@ Pass *createFunctionInliningPass(); //===----------------------------------------------------------------------===// +// createPruneEHPass - Return a new pass object which transforms invoke +// instructions into calls, if the callee can _not_ unwind the stack. +// +Pass *createPruneEHPass(); + +//===----------------------------------------------------------------------===// // createInternalizePass - This pass loops over all of the functions in the // input module, looking for a main function. If a main function is found, all // other functions are marked as internal. From lattner at cs.uiuc.edu Sun Aug 31 11:31:08 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 11:31:08 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/PruneEH.cpp Message-ID: <200308311630.LAA10304@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: PruneEH.cpp updated: 1.1 -> 1.2 --- Log message: Add accessor function --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/PruneEH.cpp diff -u llvm/lib/Transforms/IPO/PruneEH.cpp:1.1 llvm/lib/Transforms/IPO/PruneEH.cpp:1.2 --- llvm/lib/Transforms/IPO/PruneEH.cpp:1.1 Sat Aug 30 21:47:32 2003 +++ llvm/lib/Transforms/IPO/PruneEH.cpp Sun Aug 31 11:30:07 2003 @@ -30,6 +30,8 @@ RegisterOpt X("prune-eh", "Remove unused exception handling info"); } +Pass *createPruneEHPass() { return new PruneEH(); } + bool PruneEH::runOnSCC(const std::vector &SCC) { CallGraph &CG = getAnalysis(); From brukman at cs.uiuc.edu Sun Aug 31 12:10:02 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Sun Aug 31 12:10:02 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/RunSafely.sh Message-ID: <200308311709.MAA06198@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs: RunSafely.sh updated: 1.9 -> 1.10 --- Log message: Set a limit on files being output to prevent filling up the disk when a test causes an infinite loop. --- Diffs of the changes: Index: llvm/test/Programs/RunSafely.sh diff -u llvm/test/Programs/RunSafely.sh:1.9 llvm/test/Programs/RunSafely.sh:1.10 --- llvm/test/Programs/RunSafely.sh:1.9 Thu Jul 3 12:50:57 2003 +++ llvm/test/Programs/RunSafely.sh Sun Aug 31 12:09:15 2003 @@ -25,6 +25,9 @@ ulimit -t $ULIMIT rm -f core core.* ulimit -c unlimited +# To prevent infinite loops which fill up the disk, specify a limit on size of +# files being output by the tests. 1 MB should be enough for anybody. ;) +ulimit -f 1048576 # # If we are on a sun4u machine (UltraSparc), then the code we're generating From brukman at cs.uiuc.edu Sun Aug 31 12:12:02 2003 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Sun Aug 31 12:12:02 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/RunSafely.sh Message-ID: <200308311711.MAA06271@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs: RunSafely.sh updated: 1.10 -> 1.11 --- Log message: 1 MB isn't enough -- anagram makes over 2 MB of output. Let's say 10 MB is the limit. --- Diffs of the changes: Index: llvm/test/Programs/RunSafely.sh diff -u llvm/test/Programs/RunSafely.sh:1.10 llvm/test/Programs/RunSafely.sh:1.11 --- llvm/test/Programs/RunSafely.sh:1.10 Sun Aug 31 12:09:15 2003 +++ llvm/test/Programs/RunSafely.sh Sun Aug 31 12:10:55 2003 @@ -26,8 +26,8 @@ rm -f core core.* ulimit -c unlimited # To prevent infinite loops which fill up the disk, specify a limit on size of -# files being output by the tests. 1 MB should be enough for anybody. ;) -ulimit -f 1048576 +# files being output by the tests. 10 MB should be enough for anybody. ;) +ulimit -f 10485760 # # If we are on a sun4u machine (UltraSparc), then the code we're generating From lattner at cs.uiuc.edu Sun Aug 31 14:11:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:11:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/Inliner.cpp Inliner.h InlineSimple.cpp Message-ID: <200308311910.OAA21122@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: Inliner.cpp added (r1.1) Inliner.h added (r1.1) InlineSimple.cpp updated: 1.49 -> 1.50 --- Log message: Heavily refactor code: * Separate the policy decisions into a derived class [InlineSimple] * Move the inlining mechanics into a base class [Inliner] * Change the inliner to be an SCCPass, making it more structured and eventually pipelinable with other SCC passes --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/Inliner.cpp diff -c /dev/null llvm/lib/Transforms/IPO/Inliner.cpp:1.1 *** /dev/null Sun Aug 31 14:10:40 2003 --- llvm/lib/Transforms/IPO/Inliner.cpp Sun Aug 31 14:10:30 2003 *************** *** 0 **** --- 1,119 ---- + //===- InlineCommon.cpp - Code common to all inliners ---------------------===// + // + // This file implements the code shared between the LLVM inliners. This + // implements all of the boring mechanics of the bottom-up inlining. + // + //===----------------------------------------------------------------------===// + + #include "Inliner.h" + #include "llvm/Module.h" + #include "llvm/iOther.h" + #include "llvm/iTerminators.h" + #include "llvm/Analysis/CallGraph.h" + #include "llvm/Support/CallSite.h" + #include "llvm/Transforms/Utils/Cloning.h" + #include "Support/CommandLine.h" + #include "Support/Debug.h" + #include "Support/Statistic.h" + + namespace { + Statistic<> NumInlined("inline", "Number of functions inlined"); + Statistic<> NumDeleted("inline", "Number of functions deleted because all callers found"); + cl::opt // FIXME: 200 is VERY conservative + InlineLimit("inline-threshold", cl::Hidden, cl::init(200), + cl::desc("Control the amount of inlining to perform (default = 200)")); + } + + Inliner::Inliner() : InlineThreshold(InlineLimit) {} + + int Inliner::getRecursiveInlineCost(CallSite CS) { + return getInlineCost(CS); + } + + bool Inliner::runOnSCC(const std::vector &SCC) { + CallGraph &CG = getAnalysis(); + + std::set SCCFunctions; + DEBUG(std::cerr << "Inliner visiting SCC:"); + for (unsigned i = 0, e = SCC.size(); i != e; ++i) { + SCCFunctions.insert(SCC[i]->getFunction()); + DEBUG(std::cerr << " " << (SCC[i]->getFunction() ? + SCC[i]->getFunction()->getName() : "INDIRECTNODE")); + } + DEBUG(std::cerr << "\n"); + + bool Changed = false; + for (std::set::iterator SCCI = SCCFunctions.begin(), + E = SCCFunctions.end(); SCCI != E; ++SCCI) { + Function *F = *SCCI; + if (F == 0 || F->isExternal()) continue; + DEBUG(std::cerr << " Inspecting function: " << F->getName() << "\n"); + + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) + for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ) { + bool ShouldInc = true; + // Found a call or invoke instruction? + if (isa(I) || isa(I)) { + CallSite CS = CallSite::get(I); + if (Function *Callee = CS.getCalledFunction()) + if (!Callee->isExternal()) { + // Determine whether this is a function IN the SCC... + bool inSCC = SCCFunctions.count(Callee); + + // If the policy determines that we should inline this function, + // try to do so... + int InlineCost = inSCC ? getRecursiveInlineCost(CS) : + getInlineCost(CS); + if (InlineCost < (int)InlineThreshold) { + DEBUG(std::cerr << " Inlining: cost=" << InlineCost + << ", Call: " << *CS.getInstruction()); + + // Save an iterator to the instruction before the call if it + // exists, otherwise get an iterator at the end of the + // block... because the call will be destroyed. + // + BasicBlock::iterator SI; + if (I != BB->begin()) { + SI = I; --SI; // Instruction before the call... + } else { + SI = BB->end(); + } + + if (performInlining(CS, SCCFunctions)) { + // Move to instruction before the call... + I = (SI == BB->end()) ? BB->begin() : SI; + ShouldInc = false; // Don't increment iterator until next time + Changed = true; + } + } + } + } + if (ShouldInc) ++I; + } + } + return Changed; + } + + bool Inliner::performInlining(CallSite CS, std::set &SCC) { + Function *Callee = CS.getCalledFunction(); + Function *Caller = CS.getInstruction()->getParent()->getParent(); + + // Attempt to inline the function... + if (!InlineFunction(CS)) return false; + ++NumInlined; + + // If we inlined the last possible call site to the function, + // delete the function body now. + if (Callee->use_empty() && Callee != Caller && + (Callee->hasInternalLinkage() || Callee->hasLinkOnceLinkage())) { + DEBUG(std::cerr << " -> Deleting dead function: " + << Callee->getName() << "\n"); + std::set::iterator I = SCC.find(Callee); + if (I != SCC.end()) // Remove function from this SCC... + SCC.erase(I); + + Callee->getParent()->getFunctionList().erase(Callee); + ++NumDeleted; + } + return true; + } Index: llvm/lib/Transforms/IPO/Inliner.h diff -c /dev/null llvm/lib/Transforms/IPO/Inliner.h:1.1 *** /dev/null Sun Aug 31 14:10:40 2003 --- llvm/lib/Transforms/IPO/Inliner.h Sun Aug 31 14:10:30 2003 *************** *** 0 **** --- 1,52 ---- + //===- InlineCommon.h - Code common to all inliners -------------*- C++ -*-===// + // + // This file defines a simple policy-based bottom-up inliner. This file + // implements all of the boring mechanics of the bottom-up inlining, while the + // subclass determines WHAT to inline, which is the much more interesting + // component. + // + //===----------------------------------------------------------------------===// + + #ifndef INLINER_H + #define INLINER_H + + #define DEBUG_TYPE "inline" + #include "llvm/CallGraphSCCPass.h" + #include + class CallSite; + + /// Inliner - This class contains all of the helper code which is used to + /// perform the inlining operations that does not depend on the policy. + /// + struct Inliner : public CallGraphSCCPass { + Inliner(); + + // Main run interface method, this implements the interface required by the + // Pass class. + virtual bool runOnSCC(const std::vector &SCC); + + /// This method returns the value specified by the -inline-threshold value, + /// specified on the command line. This is typically not directly needed. + /// + unsigned getInlineThreshold() const { return InlineThreshold; } + + /// getInlineCost - This method must be implemented by the subclass to + /// determine the cost of inlining the specified call site. If the cost + /// returned is greater than the current inline threshold, the call site is + /// not inlined. + /// + virtual int getInlineCost(CallSite CS) = 0; + + /// getRecursiveInlineCost - This method can be implemented by subclasses if + /// it wants to treat calls to functions within the current SCC specially. If + /// this method is not overloaded, it just chains to getInlineCost(). + /// + virtual int getRecursiveInlineCost(CallSite CS); + + private: + unsigned InlineThreshold; + bool performInlining(CallSite CS, std::set &SCC); + }; + + + #endif Index: llvm/lib/Transforms/IPO/InlineSimple.cpp diff -u llvm/lib/Transforms/IPO/InlineSimple.cpp:1.49 llvm/lib/Transforms/IPO/InlineSimple.cpp:1.50 --- llvm/lib/Transforms/IPO/InlineSimple.cpp:1.49 Sun Aug 24 01:59:28 2003 +++ llvm/lib/Transforms/IPO/InlineSimple.cpp Sun Aug 31 14:10:30 2003 @@ -1,77 +1,47 @@ -//===- FunctionInlining.cpp - Code to perform function inlining -----------===// +//===- InlineSimple.cpp - Code to perform simple function inlining --------===// // // This file implements bottom-up inlining of functions into callees. // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "inline" -#include "llvm/Transforms/IPO.h" -#include "llvm/Module.h" -#include "llvm/Pass.h" -#include "llvm/iOther.h" +#include "Inliner.h" +#include "llvm/Function.h" #include "llvm/iMemory.h" -#include "llvm/iTerminators.h" #include "llvm/Support/CallSite.h" -#include "llvm/Transforms/Utils/Cloning.h" -#include "Support/CommandLine.h" -#include "Support/Debug.h" -#include "Support/Statistic.h" -#include +#include "llvm/Transforms/IPO.h" namespace { - Statistic<> NumInlined("inline", "Number of functions inlined"); - Statistic<> NumDeleted("inline", "Number of functions deleted because all callers found"); - cl::opt // FIXME: 200 is VERY conservative - InlineLimit("inline-threshold", cl::Hidden, cl::init(200), - cl::desc("Control the amount of inlining to perform (default = 200)")); - - struct FunctionInlining : public Pass { - virtual bool run(Module &M) { - bool Changed = false; - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - Changed |= doInlining(I); - ProcessedFunctions.clear(); - return Changed; - } - - private: - std::set ProcessedFunctions; // Prevent infinite recursion - bool doInlining(Function *F); + struct SimpleInliner : public Inliner { + int getInlineCost(CallSite CS); }; - RegisterOpt X("inline", "Function Integration/Inlining"); + RegisterOpt X("inline", "Function Integration/Inlining"); } -Pass *createFunctionInliningPass() { return new FunctionInlining(); } +Pass *createFunctionInliningPass() { return new SimpleInliner(); } -// ShouldInlineFunction - The heuristic used to determine if we should inline -// the function call or not. +// getInlineCost - The heuristic used to determine if we should inline the +// function call or not. // -static inline bool ShouldInlineFunction(CallSite CS) { +int SimpleInliner::getInlineCost(CallSite CS) { Instruction *TheCall = CS.getInstruction(); - assert(TheCall->getParent() && TheCall->getParent()->getParent() && - "Call not embedded into a function!"); - const Function *Callee = CS.getCalledFunction(); - if (Callee == 0 || Callee->isExternal()) - return false; // Cannot inline an indirect call... or external function. - - // Don't inline a recursive call. const Function *Caller = TheCall->getParent()->getParent(); - if (Caller == Callee) return false; - // InlineQuality - This value measures how good of an inline candidate this - // call site is to inline. The initial value determines how aggressive the - // inliner is. If this value is negative after the final computation, - // inlining is not performed. + // Don't inline a directly recursive call. + if (Caller == Callee) return 2000000000; + + // InlineCost - This value measures how good of an inline candidate this call + // site is to inline. A lower inline cost make is more likely for the call to + // be inlined. This value may go negative. // - int InlineQuality = InlineLimit; + int InlineCost = 0; // If there is only one call of the function, and it has internal linkage, // make it almost guaranteed to be inlined. // if (Callee->use_size() == 1 && Callee->hasInternalLinkage()) - InlineQuality += 30000; + InlineCost -= 30000; // Add to the inline quality for properties that make the call valueable to // inline. This includes factors that indicate that the result of inlining @@ -83,12 +53,12 @@ // Each argument passed in has a cost at both the caller and the callee // sides. This favors functions that take many arguments over functions // that take few arguments. - InlineQuality += 20; + InlineCost -= 20; // If this is a function being passed in, it is very likely that we will be // able to turn an indirect function call into a direct function call. if (isa(I)) - InlineQuality += 100; + InlineCost -= 100; // If a constant, global variable or alloca is passed in, inlining this // function is likely to allow significant future optimization possibilities @@ -96,7 +66,7 @@ // the inlining of the function. // else if (isa(I) || isa(I) || isa(I)) - InlineQuality += 60; + InlineCost -= 60; } // Now that we have considered all of the factors that make the call site more @@ -106,84 +76,14 @@ // Look at the size of the callee. Each basic block counts as 20 units, and // each instruction counts as 10. for (Function::const_iterator BB = Callee->begin(), E = Callee->end(); - BB != E; ++BB) { - InlineQuality -= BB->size()*10 + 20; - if (InlineQuality < 0) return false; - } + BB != E; ++BB) + InlineCost += BB->size()*10 + 20; // Don't inline into something too big, which would make it bigger. Here, we // count each basic block as a single unit. for (Function::const_iterator BB = Caller->begin(), E = Caller->end(); - BB != E; ++BB) { - --InlineQuality; - if (InlineQuality < 0) return false; - } + BB != E; ++BB) + InlineCost++; - // If we get here, this call site is high enough "quality" to inline. - DEBUG(std::cerr << "Inlining in '" << Caller->getName() - << "', quality = " << InlineQuality << ": " << *TheCall); - return true; + return InlineCost; } - - -// doInlining - Use a heuristic based approach to inline functions that seem to -// look good. -// -bool FunctionInlining::doInlining(Function *F) { - // If we have already processed this function (ie, it is recursive) don't - // revisit. - std::set::iterator PFI = ProcessedFunctions.lower_bound(F); - if (PFI != ProcessedFunctions.end() && *PFI == F) return false; - - // Insert the function in the set so it doesn't get revisited. - ProcessedFunctions.insert(PFI, F); - - bool Changed = false; - for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) - for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ) { - bool ShouldInc = true; - // Found a call or invoke instruction? - if (isa(I) || isa(I)) { - CallSite CS = CallSite::get(I); - if (Function *Callee = CS.getCalledFunction()) { - doInlining(Callee); // Inline in callees before callers! - - // Decide whether we should inline this function... - if (ShouldInlineFunction(CS)) { - // Save an iterator to the instruction before the call if it exists, - // otherwise get an iterator at the end of the block... because the - // call will be destroyed. - // - BasicBlock::iterator SI; - if (I != BB->begin()) { - SI = I; --SI; // Instruction before the call... - } else { - SI = BB->end(); - } - - // Attempt to inline the function... - if (InlineFunction(CS)) { - ++NumInlined; - Changed = true; - // Move to instruction before the call... - I = (SI == BB->end()) ? BB->begin() : SI; - ShouldInc = false; // Don't increment iterator until next time - - // If we inlined the last possible call site to the function, - // delete the function body now. - if (Callee->use_empty() && - (Callee->hasInternalLinkage()||Callee->hasLinkOnceLinkage())){ - F->getParent()->getFunctionList().erase(Callee); - ++NumDeleted; - if (Callee == F) return true; - } - } - } - } - } - if (ShouldInc) ++I; - } - - return Changed; -} - From lattner at cs.uiuc.edu Sun Aug 31 14:24:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:24:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/PrintSCC.cpp Message-ID: <200308311923.OAA23588@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: PrintSCC.cpp updated: 1.1 -> 1.2 --- Log message: * Cleanups * Iterate from tarj_begin -> tarj_end, not from tarj_begin -> NULL --- Diffs of the changes: Index: llvm/lib/Analysis/PrintSCC.cpp diff -u llvm/lib/Analysis/PrintSCC.cpp:1.1 llvm/lib/Analysis/PrintSCC.cpp:1.2 --- llvm/lib/Analysis/PrintSCC.cpp:1.1 Mon Nov 4 08:20:22 2002 +++ llvm/lib/Analysis/PrintSCC.cpp Sun Aug 31 14:23:41 2003 @@ -1,4 +1,4 @@ -//===- PrintSCC.cpp - Enumerate SCCs in some key graphs ---------*- C++ -*-===// +//===- PrintSCC.cpp - Enumerate SCCs in some key graphs -------------------===// // // This file provides passes to print out SCCs in a CFG or a CallGraph. // Normally, you would not use these passes; instead, you would use the @@ -14,34 +14,30 @@ // analyze -callscc [-stats] [-debug] to print SCCs in the CallGraph // // (3) To test the TarjanSCCIterator. +// //===----------------------------------------------------------------------===// #include "llvm/Pass.h" #include "llvm/Module.h" -#include "llvm/Function.h" -#include "llvm/BasicBlock.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Support/CFG.h" #include "Support/TarjanSCCIterator.h" namespace { - -class CFGSCC: public FunctionPass { -public: +struct CFGSCC: public FunctionPass { bool runOnFunction(Function& func) { unsigned long sccNum = 0; - const SCC* nextSCC; std::cout << "SCCs for Function " << func.getName() << " in PostOrder:"; - for (TarjanSCC_iterator tarjSCCiter = tarj_begin(&func); - (nextSCC = *tarjSCCiter); ++tarjSCCiter) - { - std::cout << "\nSCC #" << ++sccNum << " : "; - for (SCC::const_iterator I=nextSCC->begin(),E=nextSCC->end(); - I != E; ++I) - std::cout << (*I)->getName() << ", "; - if (nextSCC->size() == 1 && nextSCC->HasLoop()) - std::cout << " (Has self-loop)."; - } + for (TarjanSCC_iterator I = tarj_begin(&func), + E = tarj_end(&func); I != E; ++I) { + SCC &nextSCC = **I; + std::cout << "\nSCC #" << ++sccNum << " : "; + for (SCC::const_iterator I = nextSCC.begin(),E = nextSCC.end(); + I != E; ++I) + std::cout << (*I)->getName() << ", "; + if (nextSCC.size() == 1 && nextSCC.HasLoop()) + std::cout << " (Has self-loop)."; + } std::cout << "\n"; return true; @@ -50,26 +46,23 @@ }; -class CallGraphSCC: public Pass { -public: +struct CallGraphSCC : public Pass { // run - Print out SCCs in the call graph for the specified module. - bool run(Module& M) { + bool run(Module &M) { CallGraphNode* rootNode = getAnalysis().getRoot(); unsigned long sccNum = 0; - const SCC* nextSCC; std::cout << "SCCs for the program in PostOrder:"; - for (TarjanSCC_iterator tarjSCCiter = tarj_begin(rootNode); - (nextSCC = *tarjSCCiter); ++tarjSCCiter) - { - std::cout << "\nSCC #" << ++sccNum << " : "; - for (SCC::const_iterator I=nextSCC->begin(), - E=nextSCC->end(); I != E; ++I) - std::cout << ((*I)->getFunction()? (*I)->getFunction()->getName() - : std::string("Null CallGraph node")) - << ", "; - if (nextSCC->size() == 1 && nextSCC->HasLoop()) - std::cout << " (Has self-loop)."; - } + for (TarjanSCC_iterator SCCI = tarj_begin(rootNode), + E = tarj_end(rootNode); SCCI != E; ++SCCI) { + const SCC &nextSCC = **SCCI; + std::cout << "\nSCC #" << ++sccNum << " : "; + for (SCC::const_iterator I = nextSCC.begin(), + E = nextSCC.end(); I != E; ++I) + std::cout << ((*I)->getFunction() ? (*I)->getFunction()->getName() + : std::string("Indirect CallGraph node")) << ", "; + if (nextSCC.size() == 1 && nextSCC.HasLoop()) + std::cout << " (Has self-loop)."; + } std::cout << "\n"; return true; @@ -84,10 +77,9 @@ } }; -static RegisterAnalysis -Y("cfgscc", "Print SCCs of each function CFG"); - -static RegisterAnalysis -Z("callscc", "Print SCCs of the Call Graph"); + RegisterAnalysis + Y("cfgscc", "Print SCCs of each function CFG"); + RegisterAnalysis + Z("callscc", "Print SCCs of the Call Graph"); } From lattner at cs.uiuc.edu Sun Aug 31 14:28:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:28:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/PrintSCC.cpp Message-ID: <200308311927.OAA24281@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: PrintSCC.cpp updated: 1.2 -> 1.3 --- Log message: Indent classes correctly in the namespace move bodies out-of-line Add getAnalysisUsage method for SFGSCC --- Diffs of the changes: Index: llvm/lib/Analysis/PrintSCC.cpp diff -u llvm/lib/Analysis/PrintSCC.cpp:1.2 llvm/lib/Analysis/PrintSCC.cpp:1.3 --- llvm/lib/Analysis/PrintSCC.cpp:1.2 Sun Aug 31 14:23:41 2003 +++ llvm/lib/Analysis/PrintSCC.cpp Sun Aug 31 14:27:11 2003 @@ -24,62 +24,72 @@ #include "Support/TarjanSCCIterator.h" namespace { -struct CFGSCC: public FunctionPass { - bool runOnFunction(Function& func) { - unsigned long sccNum = 0; - std::cout << "SCCs for Function " << func.getName() << " in PostOrder:"; - for (TarjanSCC_iterator I = tarj_begin(&func), - E = tarj_end(&func); I != E; ++I) { - SCC &nextSCC = **I; - std::cout << "\nSCC #" << ++sccNum << " : "; - for (SCC::const_iterator I = nextSCC.begin(),E = nextSCC.end(); - I != E; ++I) - std::cout << (*I)->getName() << ", "; - if (nextSCC.size() == 1 && nextSCC.HasLoop()) - std::cout << " (Has self-loop)."; - } - std::cout << "\n"; - - return true; - } - void print(std::ostream &O) const { } -}; + struct CFGSCC : public FunctionPass { + bool runOnFunction(Function& func); + void print(std::ostream &O) const { } -struct CallGraphSCC : public Pass { - // run - Print out SCCs in the call graph for the specified module. - bool run(Module &M) { - CallGraphNode* rootNode = getAnalysis().getRoot(); - unsigned long sccNum = 0; - std::cout << "SCCs for the program in PostOrder:"; - for (TarjanSCC_iterator SCCI = tarj_begin(rootNode), - E = tarj_end(rootNode); SCCI != E; ++SCCI) { - const SCC &nextSCC = **SCCI; - std::cout << "\nSCC #" << ++sccNum << " : "; - for (SCC::const_iterator I = nextSCC.begin(), - E = nextSCC.end(); I != E; ++I) - std::cout << ((*I)->getFunction() ? (*I)->getFunction()->getName() - : std::string("Indirect CallGraph node")) << ", "; - if (nextSCC.size() == 1 && nextSCC.HasLoop()) - std::cout << " (Has self-loop)."; + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); } - std::cout << "\n"; + }; - return true; - } - - void print(std::ostream &O) const { } - - // getAnalysisUsage - This pass requires the CallGraph. - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequired(); - } -}; + struct CallGraphSCC : public Pass { + // run - Print out SCCs in the call graph for the specified module. + bool run(Module &M); + + void print(std::ostream &O) const { } + + // getAnalysisUsage - This pass requires the CallGraph. + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired(); + } + }; RegisterAnalysis Y("cfgscc", "Print SCCs of each function CFG"); RegisterAnalysis Z("callscc", "Print SCCs of the Call Graph"); +} + +bool CFGSCC::runOnFunction(Function &F) { + unsigned sccNum = 0; + std::cout << "SCCs for Function " << F.getName() << " in PostOrder:"; + for (TarjanSCC_iterator I = tarj_begin(&F), + E = tarj_end(&F); I != E; ++I) { + SCC &nextSCC = **I; + std::cout << "\nSCC #" << ++sccNum << " : "; + for (SCC::const_iterator I = nextSCC.begin(), + E = nextSCC.end(); I != E; ++I) + std::cout << (*I)->getName() << ", "; + if (nextSCC.size() == 1 && nextSCC.HasLoop()) + std::cout << " (Has self-loop)."; + } + std::cout << "\n"; + + return true; +} + + +// run - Print out SCCs in the call graph for the specified module. +bool CallGraphSCC::run(Module &M) { + CallGraphNode* rootNode = getAnalysis().getRoot(); + unsigned sccNum = 0; + std::cout << "SCCs for the program in PostOrder:"; + for (TarjanSCC_iterator SCCI = tarj_begin(rootNode), + E = tarj_end(rootNode); SCCI != E; ++SCCI) { + const SCC &nextSCC = **SCCI; + std::cout << "\nSCC #" << ++sccNum << " : "; + for (SCC::const_iterator I = nextSCC.begin(), + E = nextSCC.end(); I != E; ++I) + std::cout << ((*I)->getFunction() ? (*I)->getFunction()->getName() + : std::string("Indirect CallGraph node")) << ", "; + if (nextSCC.size() == 1 && nextSCC.HasLoop()) + std::cout << " (Has self-loop)."; + } + std::cout << "\n"; + + return true; } From lattner at cs.uiuc.edu Sun Aug 31 14:31:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:31:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp Message-ID: <200308311930.OAA24616@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: MemoryDepAnalysis.cpp updated: 1.2 -> 1.3 --- Log message: Minor cleanups Iterate from tarj_begin -> tarj_end, not from tarj_begin -> NULL --- Diffs of the changes: Index: llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp diff -u llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.2 llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.3 --- llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.2 Wed Aug 6 12:16:19 2003 +++ llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp Sun Aug 31 14:29:52 2003 @@ -14,7 +14,6 @@ #include "llvm/Analysis/DataStructure.h" #include "llvm/Analysis/DSGraph.h" #include "llvm/Module.h" -#include "llvm/Function.h" #include "llvm/iMemory.h" #include "llvm/iOther.h" #include "llvm/Support/InstVisitor.h" @@ -24,7 +23,6 @@ #include "Support/STLExtras.h" #include "Support/hash_map" #include "Support/hash_set" -#include ///-------------------------------------------------------------------------- @@ -263,10 +261,8 @@ /// } /// /// - void MemoryDepAnalysis::ProcessSCC(SCC& S, - ModRefTable& ModRefAfter) -{ + ModRefTable& ModRefAfter) { ModRefTable ModRefCurrent; ModRefTable::ModRefMap& mapCurrent = ModRefCurrent.modRefMap; ModRefTable::ModRefMap& mapAfter = ModRefAfter.modRefMap; @@ -417,27 +413,26 @@ /// /// Run the pass on a function /// -bool MemoryDepAnalysis::runOnFunction(Function& func) -{ - assert(! func.isExternal()); +bool MemoryDepAnalysis::runOnFunction(Function &F) { + assert(!F.isExternal()); // Get the FunctionModRefInfo holding IPModRef results for this function. // Use the TD graph recorded within the FunctionModRefInfo object, which // may not be the same as the original TD graph computed by DS analysis. // - funcModRef = &getAnalysis().getFunctionModRefInfo(func); + funcModRef = &getAnalysis().getFunctionModRefInfo(F); funcGraph = &funcModRef->getFuncGraph(); // TEMPORARY: ptr to depGraph (later just becomes "this"). - assert(funcMap.find(&func) == funcMap.end() && "Analyzing function twice?"); - funcDepGraph = funcMap[&func] = new DependenceGraph(); + assert(!funcMap.count(&F) && "Analyzing function twice?"); + funcDepGraph = funcMap[&F] = new DependenceGraph(); ModRefTable ModRefAfter; SCC* nextSCC; - for (TarjanSCC_iterator tarjSCCiter = tarj_begin(&func); - (nextSCC = *tarjSCCiter) != NULL; ++tarjSCCiter) - ProcessSCC(*nextSCC, ModRefAfter); + for (TarjanSCC_iterator I = tarj_begin(&F), E = tarj_end(&F); + I != E; ++I) + ProcessSCC(**I, ModRefAfter); return true; } From lattner at cs.uiuc.edu Sun Aug 31 14:35:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:35:01 2003 Subject: [llvm-commits] CVS: llvm/include/Support/TarjanSCCIterator.h Message-ID: <200308311934.OAA26461@apoc.cs.uiuc.edu> Changes in directory llvm/include/Support: TarjanSCCIterator.h updated: 1.11 -> 1.12 --- Log message: * Cleanups * operator* now returns a reference to the current SCC, instead of a possibly null pointer --- Diffs of the changes: Index: llvm/include/Support/TarjanSCCIterator.h diff -u llvm/include/Support/TarjanSCCIterator.h:1.11 llvm/include/Support/TarjanSCCIterator.h:1.12 --- llvm/include/Support/TarjanSCCIterator.h:1.11 Sat Aug 30 20:48:21 2003 +++ llvm/include/Support/TarjanSCCIterator.h Sun Aug 31 14:34:27 2003 @@ -16,17 +16,16 @@ #define SUPPORT_TARJANSCCITERATOR_H #include "Support/GraphTraits.h" -#include "Support/Debug.h" #include "Support/iterator" #include #include //-------------------------------------------------------------------------- -// class SCC : A simple representation of an SCC in a generic Graph. +// class SCC - A simple representation of an SCC in a generic Graph. //-------------------------------------------------------------------------- template > -struct SCC: public std::vector { +struct SCC : public std::vector { typedef typename GT::NodeType NodeType; typedef typename GT::ChildIteratorType ChildItTy; @@ -43,7 +42,7 @@ bool HasLoop() const { if (size() > 1) return true; NodeType* N = front(); - for (ChildItTy CI=GT::child_begin(N), CE=GT::child_end(N); CI != CE; ++CI) + for (ChildItTy CI = GT::child_begin(N), CE=GT::child_end(N); CI != CE; ++CI) if (*CI == N) return true; return false; @@ -56,8 +55,7 @@ //-------------------------------------------------------------------------- template > -class TarjanSCC_iterator : public forward_iterator, ptrdiff_t> -{ +class TarjanSCC_iterator : public forward_iterator, ptrdiff_t> { typedef SCC SccTy; typedef forward_iterator super; typedef typename super::reference reference; @@ -185,32 +183,27 @@ _Self tmp = *this; ++*this; return tmp; } - // Retrieve a pointer to the current SCC. Returns NULL when done. - inline const SccTy* operator*() const { - assert(!CurrentSCC.empty() || VisitStack.empty()); - return CurrentSCC.empty()? NULL : &CurrentSCC; - } - inline SccTy* operator*() { - assert(!CurrentSCC.empty() || VisitStack.empty()); - return CurrentSCC.empty()? NULL : &CurrentSCC; + // Retrieve a reference to the current SCC + inline const SccTy &operator*() const { + assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!"); + return CurrentSCC; + } + inline SccTy &operator*() { + assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!"); + return CurrentSCC; } }; -// Global constructor for the Tarjan SCC iterator. Use *I == NULL or I.fini() -// to test termination efficiently, instead of I == the "end" iterator. +// Global constructor for the Tarjan SCC iterator. template -TarjanSCC_iterator tarj_begin(T G) -{ +TarjanSCC_iterator tarj_begin(T G) { return TarjanSCC_iterator::begin(G); } template -TarjanSCC_iterator tarj_end(T G) -{ +TarjanSCC_iterator tarj_end(T G) { return TarjanSCC_iterator::end(G); } - -//===----------------------------------------------------------------------===// #endif From lattner at cs.uiuc.edu Sun Aug 31 14:36:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:36:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp MemoryDepAnalysis.cpp Message-ID: <200308311935.OAA26503@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: CallGraphSCCPass.cpp updated: 1.1 -> 1.2 MemoryDepAnalysis.cpp updated: 1.3 -> 1.4 --- Log message: The tarjan iterator now returns a reference to the current SCC, not a possibly null pointer! --- Diffs of the changes: Index: llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp diff -u llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp:1.1 llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp:1.2 --- llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp:1.1 Sat Aug 30 20:54:57 2003 +++ llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp Sun Aug 31 14:35:16 2003 @@ -25,6 +25,6 @@ bool Changed = false; for (TarjanSCC_iterator I = tarj_begin(&CG), E = tarj_end(&CG); I != E; ++I) - Changed = runOnSCC(**I); + Changed = runOnSCC(*I); return Changed; } Index: llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp diff -u llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.3 llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.4 --- llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.3 Sun Aug 31 14:29:52 2003 +++ llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp Sun Aug 31 14:35:16 2003 @@ -432,7 +432,7 @@ SCC* nextSCC; for (TarjanSCC_iterator I = tarj_begin(&F), E = tarj_end(&F); I != E; ++I) - ProcessSCC(**I, ModRefAfter); + ProcessSCC(*I, ModRefAfter); return true; } From lattner at cs.uiuc.edu Sun Aug 31 14:36:09 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:36:09 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/PrintSCC.cpp Message-ID: <200308311935.OAA26494@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: PrintSCC.cpp updated: 1.3 -> 1.4 --- Log message: The tarjan iterator now returns a reference to the current SCC, not a possibly null pointer! --- Diffs of the changes: Index: llvm/lib/Analysis/PrintSCC.cpp diff -u llvm/lib/Analysis/PrintSCC.cpp:1.3 llvm/lib/Analysis/PrintSCC.cpp:1.4 --- llvm/lib/Analysis/PrintSCC.cpp:1.3 Sun Aug 31 14:27:11 2003 +++ llvm/lib/Analysis/PrintSCC.cpp Sun Aug 31 14:35:14 2003 @@ -59,7 +59,7 @@ std::cout << "SCCs for Function " << F.getName() << " in PostOrder:"; for (TarjanSCC_iterator I = tarj_begin(&F), E = tarj_end(&F); I != E; ++I) { - SCC &nextSCC = **I; + SCC &nextSCC = *I; std::cout << "\nSCC #" << ++sccNum << " : "; for (SCC::const_iterator I = nextSCC.begin(), E = nextSCC.end(); I != E; ++I) @@ -80,7 +80,7 @@ std::cout << "SCCs for the program in PostOrder:"; for (TarjanSCC_iterator SCCI = tarj_begin(rootNode), E = tarj_end(rootNode); SCCI != E; ++SCCI) { - const SCC &nextSCC = **SCCI; + const SCC &nextSCC = *SCCI; std::cout << "\nSCC #" << ++sccNum << " : "; for (SCC::const_iterator I = nextSCC.begin(), E = nextSCC.end(); I != E; ++I) From lattner at cs.uiuc.edu Sun Aug 31 14:38:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:38:02 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Utils/Cloning.h Message-ID: <200308311937.OAA27301@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms/Utils: Cloning.h updated: 1.10 -> 1.11 --- Log message: Fix an FLAT OUT WRONG comment --- Diffs of the changes: Index: llvm/include/llvm/Transforms/Utils/Cloning.h diff -u llvm/include/llvm/Transforms/Utils/Cloning.h:1.10 llvm/include/llvm/Transforms/Utils/Cloning.h:1.11 --- llvm/include/llvm/Transforms/Utils/Cloning.h:1.10 Sun Aug 24 01:58:32 2003 +++ llvm/include/llvm/Transforms/Utils/Cloning.h Sun Aug 31 14:37:29 2003 @@ -83,8 +83,9 @@ /// InlineFunction - This function inlines the called function into the basic -/// block of the caller. This returns true if it is not possible to inline this -/// call. The program is still in a well defined state if this occurs though. +/// block of the caller. This returns false if it is not possible to inline +/// this call. The program is still in a well defined state if this occurs +/// though. /// /// Note that this only does one level of inlining. For example, if the /// instruction 'call B' is inlined, and 'B' calls 'C', then the call to 'C' now From lattner at cs.uiuc.edu Sun Aug 31 14:42:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:42:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/MemoryDepAnalysis.h Message-ID: <200308311941.OAA28501@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: MemoryDepAnalysis.h updated: 1.3 -> 1.4 --- Log message: Cleanups, move the getAnalysisUsage method to the .cpp file --- Diffs of the changes: Index: llvm/include/llvm/Analysis/MemoryDepAnalysis.h diff -u llvm/include/llvm/Analysis/MemoryDepAnalysis.h:1.3 llvm/include/llvm/Analysis/MemoryDepAnalysis.h:1.4 --- llvm/include/llvm/Analysis/MemoryDepAnalysis.h:1.3 Sat Jun 21 22:05:45 2003 +++ llvm/include/llvm/Analysis/MemoryDepAnalysis.h Sun Aug 31 14:41:17 2003 @@ -14,14 +14,13 @@ #define LLVM_ANALYSIS_MEMORYDEPANALYSIS_H #include "llvm/Analysis/DependenceGraph.h" -#include "llvm/Analysis/IPModRef.h" -#include "llvm/Analysis/DataStructure.h" #include "llvm/Pass.h" #include "Support/TarjanSCCIterator.h" #include "Support/hash_map" -class Instruction; class ModRefTable; +class DSGraph; +class FunctionModRefInfo; ///--------------------------------------------------------------------------- /// class MemoryDepGraph: @@ -33,8 +32,7 @@ /// allowed to use a FunctionPass such as this one. ///--------------------------------------------------------------------------- -class MemoryDepAnalysis: /* Use if FunctionPass: public DependenceGraph, */ - public Pass { +class MemoryDepAnalysis : public Pass { /// The following map and depGraph pointer are temporary until this class /// becomes a FunctionPass instead of a module Pass. */ hash_map funcMap; @@ -45,23 +43,16 @@ const FunctionModRefInfo* funcModRef; /// Internal routine that processes each SCC of the CFG. - void MemoryDepAnalysis::ProcessSCC(SCC& S, - ModRefTable& ModRefAfter); + void ProcessSCC(SCC& S, ModRefTable& ModRefAfter); friend class PgmDependenceGraph; public: - MemoryDepAnalysis() - : /*DependenceGraph(),*/ funcDepGraph(NULL), - funcGraph(NULL), funcModRef(NULL) { } + MemoryDepAnalysis() : funcDepGraph(0), funcGraph(0), funcModRef(0) {} ~MemoryDepAnalysis(); - ///------------------------------------------------------------------------ - /// TEMPORARY FUNCTIONS TO MAKE THIS A MODULE PASS --- - /// These functions will go away once this class becomes a FunctionPass. - /// Driver function to compute dependence graphs for every function. - bool run(Module& M); + bool run(Module &M); /// getGraph() -- Retrieve the dependence graph for a function. /// This is temporary and will go away once this is a FunctionPass. @@ -83,29 +74,19 @@ /// virtual void releaseMemory(); - ///----END TEMPORARY FUNCTIONS--------------------------------------------- - /// Driver functions to compute the Load/Store Dep. Graph per function. /// - bool runOnFunction(Function& _func); + bool runOnFunction(Function &F); - /// getAnalysisUsage - This does not modify anything. - /// It uses the Top-Down DS Graph and IPModRef. - /// - void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequired(); - AU.addRequired(); - } + /// getAnalysisUsage - This does not modify anything. It uses the Top-Down DS + /// Graph and IPModRef. + void getAnalysisUsage(AnalysisUsage &AU) const; /// Debugging support methods /// void print(std::ostream &O) const; void dump() const; }; - - -//===----------------------------------------------------------------------===// #endif From lattner at cs.uiuc.edu Sun Aug 31 14:42:08 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:42:08 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp Message-ID: <200308311941.OAA28492@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: MemoryDepAnalysis.cpp updated: 1.4 -> 1.5 --- Log message: Move the getAnalysisUsage method from the header file --- Diffs of the changes: Index: llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp diff -u llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.4 llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.5 --- llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.4 Sun Aug 31 14:35:16 2003 +++ llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp Sun Aug 31 14:40:57 2003 @@ -41,8 +41,7 @@ /// not copied over from one table to another since it is no longer useful. ///-------------------------------------------------------------------------- -struct ModRefTable -{ +struct ModRefTable { typedef hash_map ModRefMap; typedef ModRefMap::const_iterator const_map_iterator; typedef ModRefMap:: iterator map_iterator; @@ -197,6 +196,17 @@ //---------------------------------------------------------------------------- // class MemoryDepAnalysis: A dep. graph for load/store/call instructions //---------------------------------------------------------------------------- + + +/// getAnalysisUsage - This does not modify anything. It uses the Top-Down DS +/// Graph and IPModRef. +/// +void MemoryDepAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired(); + AU.addRequired(); +} + /// Basic dependence gathering algorithm, using TarjanSCCIterator on CFG: /// From lattner at cs.uiuc.edu Sun Aug 31 14:47:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:47:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/MemoryDepAnalysis.h Message-ID: <200308311946.OAA30464@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: MemoryDepAnalysis.h updated: 1.4 -> 1.5 --- Log message: Remove explicit passing of SCC's around as objects. --- Diffs of the changes: Index: llvm/include/llvm/Analysis/MemoryDepAnalysis.h diff -u llvm/include/llvm/Analysis/MemoryDepAnalysis.h:1.4 llvm/include/llvm/Analysis/MemoryDepAnalysis.h:1.5 --- llvm/include/llvm/Analysis/MemoryDepAnalysis.h:1.4 Sun Aug 31 14:41:17 2003 +++ llvm/include/llvm/Analysis/MemoryDepAnalysis.h Sun Aug 31 14:46:48 2003 @@ -15,7 +15,6 @@ #include "llvm/Analysis/DependenceGraph.h" #include "llvm/Pass.h" -#include "Support/TarjanSCCIterator.h" #include "Support/hash_map" class ModRefTable; @@ -43,7 +42,8 @@ const FunctionModRefInfo* funcModRef; /// Internal routine that processes each SCC of the CFG. - void ProcessSCC(SCC& S, ModRefTable& ModRefAfter); + void ProcessSCC(std::vector &SCC, ModRefTable& ModRefAfter, + bool HasLoop); friend class PgmDependenceGraph; From lattner at cs.uiuc.edu Sun Aug 31 14:47:08 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:47:08 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp Message-ID: <200308311946.OAA30457@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: MemoryDepAnalysis.cpp updated: 1.5 -> 1.6 --- Log message: Remove explicit passing of SCC's around as objects. --- Diffs of the changes: Index: llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp diff -u llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.5 llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.6 --- llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.5 Sun Aug 31 14:40:57 2003 +++ llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp Sun Aug 31 14:46:46 2003 @@ -271,14 +271,12 @@ /// } /// /// -void MemoryDepAnalysis::ProcessSCC(SCC& S, - ModRefTable& ModRefAfter) { +void MemoryDepAnalysis::ProcessSCC(std::vector &S, + ModRefTable& ModRefAfter, bool hasLoop) { ModRefTable ModRefCurrent; ModRefTable::ModRefMap& mapCurrent = ModRefCurrent.modRefMap; ModRefTable::ModRefMap& mapAfter = ModRefAfter.modRefMap; - bool hasLoop = S.HasLoop(); - // Builder class fills out a ModRefTable one instruction at a time. // To use it, we just invoke it's visit function for each basic block: // @@ -290,7 +288,8 @@ // : Add I to ModRefCurrent.users if it uses any node // ModRefInfoBuilder builder(*funcGraph, *funcModRef, ModRefCurrent); - for (SCC::iterator BI=S.begin(), BE=S.end(); BI != BE; ++BI) + for (std::vector::iterator BI = S.begin(), BE = S.end(); + BI != BE; ++BI) // Note: BBs in the SCC<> created by TarjanSCCIterator are in postorder. for (BasicBlock::reverse_iterator II=(*BI)->rbegin(), IE=(*BI)->rend(); II != IE; ++II) @@ -442,7 +441,7 @@ SCC* nextSCC; for (TarjanSCC_iterator I = tarj_begin(&F), E = tarj_end(&F); I != E; ++I) - ProcessSCC(*I, ModRefAfter); + ProcessSCC(*I, ModRefAfter, (*I).HasLoop()); return true; } From lattner at cs.uiuc.edu Sun Aug 31 14:47:16 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:47:16 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/PgmDependenceGraph.h Message-ID: <200308311946.OAA30442@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: PgmDependenceGraph.h updated: 1.3 -> 1.4 --- Log message: This should use Support/iterator, not --- Diffs of the changes: Index: llvm/include/llvm/Analysis/PgmDependenceGraph.h diff -u llvm/include/llvm/Analysis/PgmDependenceGraph.h:1.3 llvm/include/llvm/Analysis/PgmDependenceGraph.h:1.4 --- llvm/include/llvm/Analysis/PgmDependenceGraph.h:1.3 Sat Jun 21 22:05:45 2003 +++ llvm/include/llvm/Analysis/PgmDependenceGraph.h Sun Aug 31 14:46:22 2003 @@ -37,7 +37,7 @@ /* #include "llvm/Analysis/PostDominators.h" -- see below */ #include "llvm/Instruction.h" #include "llvm/Pass.h" -#include +#include "Support/iterator" class DSGraph; class DependenceGraph; @@ -133,8 +133,7 @@ /// is normally not constructed for SSA def-use dependences). ///--------------------------------------------------------------------------- -class PDGIterator: public forward_iterator -{ +class PDGIterator: public forward_iterator { DepIterState* istate; #if 0 From lattner at cs.uiuc.edu Sun Aug 31 14:52:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:52:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp Message-ID: <200308311951.OAA32180@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: MemoryDepAnalysis.cpp updated: 1.6 -> 1.7 --- Log message: The SCC::HasLoop method is now in the main iterator --- Diffs of the changes: Index: llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp diff -u llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.6 llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.7 --- llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.6 Sun Aug 31 14:46:46 2003 +++ llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp Sun Aug 31 14:51:38 2003 @@ -441,7 +441,7 @@ SCC* nextSCC; for (TarjanSCC_iterator I = tarj_begin(&F), E = tarj_end(&F); I != E; ++I) - ProcessSCC(*I, ModRefAfter, (*I).HasLoop()); + ProcessSCC(*I, ModRefAfter, I.hasLoop()); return true; } From lattner at cs.uiuc.edu Sun Aug 31 14:52:08 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:52:08 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/PrintSCC.cpp Message-ID: <200308311951.OAA32173@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: PrintSCC.cpp updated: 1.4 -> 1.5 --- Log message: The SCC::HasLoop method is now in the main iterator --- Diffs of the changes: Index: llvm/lib/Analysis/PrintSCC.cpp diff -u llvm/lib/Analysis/PrintSCC.cpp:1.4 llvm/lib/Analysis/PrintSCC.cpp:1.5 --- llvm/lib/Analysis/PrintSCC.cpp:1.4 Sun Aug 31 14:35:14 2003 +++ llvm/lib/Analysis/PrintSCC.cpp Sun Aug 31 14:51:36 2003 @@ -57,14 +57,14 @@ bool CFGSCC::runOnFunction(Function &F) { unsigned sccNum = 0; std::cout << "SCCs for Function " << F.getName() << " in PostOrder:"; - for (TarjanSCC_iterator I = tarj_begin(&F), - E = tarj_end(&F); I != E; ++I) { - SCC &nextSCC = *I; + for (TarjanSCC_iterator SCCI = tarj_begin(&F), + E = tarj_end(&F); SCCI != E; ++SCCI) { + SCC &nextSCC = *SCCI; std::cout << "\nSCC #" << ++sccNum << " : "; - for (SCC::const_iterator I = nextSCC.begin(), + for (std::vector::const_iterator I = nextSCC.begin(), E = nextSCC.end(); I != E; ++I) std::cout << (*I)->getName() << ", "; - if (nextSCC.size() == 1 && nextSCC.HasLoop()) + if (nextSCC.size() == 1 && SCCI.hasLoop()) std::cout << " (Has self-loop)."; } std::cout << "\n"; @@ -82,11 +82,11 @@ E = tarj_end(rootNode); SCCI != E; ++SCCI) { const SCC &nextSCC = *SCCI; std::cout << "\nSCC #" << ++sccNum << " : "; - for (SCC::const_iterator I = nextSCC.begin(), + for (std::vector::const_iterator I = nextSCC.begin(), E = nextSCC.end(); I != E; ++I) std::cout << ((*I)->getFunction() ? (*I)->getFunction()->getName() : std::string("Indirect CallGraph node")) << ", "; - if (nextSCC.size() == 1 && nextSCC.HasLoop()) + if (nextSCC.size() == 1 && SCCI.hasLoop()) std::cout << " (Has self-loop)."; } std::cout << "\n"; From lattner at cs.uiuc.edu Sun Aug 31 14:52:15 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:52:15 2003 Subject: [llvm-commits] CVS: llvm/include/Support/TarjanSCCIterator.h Message-ID: <200308311951.OAA32160@apoc.cs.uiuc.edu> Changes in directory llvm/include/Support: TarjanSCCIterator.h updated: 1.12 -> 1.13 --- Log message: Move the HasLoop method from the SCC class to the iterator class --- Diffs of the changes: Index: llvm/include/Support/TarjanSCCIterator.h diff -u llvm/include/Support/TarjanSCCIterator.h:1.12 llvm/include/Support/TarjanSCCIterator.h:1.13 --- llvm/include/Support/TarjanSCCIterator.h:1.12 Sun Aug 31 14:34:27 2003 +++ llvm/include/Support/TarjanSCCIterator.h Sun Aug 31 14:51:22 2003 @@ -35,18 +35,6 @@ typedef typename super::const_iterator const_iterator; typedef typename super::reverse_iterator reverse_iterator; typedef typename super::const_reverse_iterator const_reverse_iterator; - - // HasLoop() -- Test if this SCC has a loop. If it has more than one - // node, this is trivially true. If not, it may still contain a loop - // if the node has an edge back to itself. - bool HasLoop() const { - if (size() > 1) return true; - NodeType* N = front(); - for (ChildItTy CI = GT::child_begin(N), CE=GT::child_end(N); CI != CE; ++CI) - if (*CI == N) - return true; - return false; - } }; //-------------------------------------------------------------------------- @@ -191,6 +179,19 @@ inline SccTy &operator*() { assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!"); return CurrentSCC; + } + + // hasLoop() -- Test if the current SCC has a loop. If it has more than one + // node, this is trivially true. If not, it may still contain a loop if the + // node has an edge back to itself. + bool hasLoop() const { + assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!"); + if (CurrentSCC.size() > 1) return true; + NodeType *N = CurrentSCC.front(); + for (ChildItTy CI = GT::child_begin(N), CE=GT::child_end(N); CI != CE; ++CI) + if (*CI == N) + return true; + return false; } }; From lattner at cs.uiuc.edu Sun Aug 31 14:56:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:56:01 2003 Subject: [llvm-commits] CVS: llvm/include/Support/TarjanSCCIterator.h Message-ID: <200308311955.OAA01758@apoc.cs.uiuc.edu> Changes in directory llvm/include/Support: TarjanSCCIterator.h updated: 1.13 -> 1.14 --- Log message: ELIMINATE the SCC class completely. One less thing deriving from std::vector --- Diffs of the changes: Index: llvm/include/Support/TarjanSCCIterator.h diff -u llvm/include/Support/TarjanSCCIterator.h:1.13 llvm/include/Support/TarjanSCCIterator.h:1.14 --- llvm/include/Support/TarjanSCCIterator.h:1.13 Sun Aug 31 14:51:22 2003 +++ llvm/include/Support/TarjanSCCIterator.h Sun Aug 31 14:55:31 2003 @@ -20,36 +20,20 @@ #include #include -//-------------------------------------------------------------------------- -// class SCC - A simple representation of an SCC in a generic Graph. -//-------------------------------------------------------------------------- - +//===----------------------------------------------------------------------===// +/// +/// TarjanSCC_iterator - Enumerate the SCCs of a directed graph, in +/// reverse topological order of the SCC DAG. +/// template > -struct SCC : public std::vector { - - typedef typename GT::NodeType NodeType; +class TarjanSCC_iterator + : public forward_iterator, ptrdiff_t> { + typedef typename GT::NodeType NodeType; typedef typename GT::ChildIteratorType ChildItTy; - - typedef std::vector super; - typedef typename super::iterator iterator; - typedef typename super::const_iterator const_iterator; - typedef typename super::reverse_iterator reverse_iterator; - typedef typename super::const_reverse_iterator const_reverse_iterator; -}; - -//-------------------------------------------------------------------------- -// class TarjanSCC_iterator: Enumerate the SCCs of a directed graph, in -// reverse topological order of the SCC DAG. -//-------------------------------------------------------------------------- - -template > -class TarjanSCC_iterator : public forward_iterator, ptrdiff_t> { - typedef SCC SccTy; + typedef std::vector SccTy; typedef forward_iterator super; typedef typename super::reference reference; typedef typename super::pointer pointer; - typedef typename GT::NodeType NodeType; - typedef typename GT::ChildIteratorType ChildItTy; // The visit counters used to detect when a complete SCC is on the stack. // visitNum is the global counter. From lattner at cs.uiuc.edu Sun Aug 31 14:56:08 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:56:08 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/PrintSCC.cpp Message-ID: <200308311955.OAA01749@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: PrintSCC.cpp updated: 1.5 -> 1.6 --- Log message: Don't explicitly use the SCC class --- Diffs of the changes: Index: llvm/lib/Analysis/PrintSCC.cpp diff -u llvm/lib/Analysis/PrintSCC.cpp:1.5 llvm/lib/Analysis/PrintSCC.cpp:1.6 --- llvm/lib/Analysis/PrintSCC.cpp:1.5 Sun Aug 31 14:51:36 2003 +++ llvm/lib/Analysis/PrintSCC.cpp Sun Aug 31 14:55:06 2003 @@ -59,7 +59,7 @@ std::cout << "SCCs for Function " << F.getName() << " in PostOrder:"; for (TarjanSCC_iterator SCCI = tarj_begin(&F), E = tarj_end(&F); SCCI != E; ++SCCI) { - SCC &nextSCC = *SCCI; + std::vector &nextSCC = *SCCI; std::cout << "\nSCC #" << ++sccNum << " : "; for (std::vector::const_iterator I = nextSCC.begin(), E = nextSCC.end(); I != E; ++I) @@ -80,7 +80,7 @@ std::cout << "SCCs for the program in PostOrder:"; for (TarjanSCC_iterator SCCI = tarj_begin(rootNode), E = tarj_end(rootNode); SCCI != E; ++SCCI) { - const SCC &nextSCC = *SCCI; + const std::vector &nextSCC = *SCCI; std::cout << "\nSCC #" << ++sccNum << " : "; for (std::vector::const_iterator I = nextSCC.begin(), E = nextSCC.end(); I != E; ++I) From lattner at cs.uiuc.edu Sun Aug 31 14:56:15 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 14:56:15 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp Message-ID: <200308311955.OAA01738@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: MemoryDepAnalysis.cpp updated: 1.7 -> 1.8 --- Log message: Remove dead var --- Diffs of the changes: Index: llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp diff -u llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.7 llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.8 --- llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.7 Sun Aug 31 14:51:38 2003 +++ llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp Sun Aug 31 14:54:57 2003 @@ -438,7 +438,6 @@ ModRefTable ModRefAfter; - SCC* nextSCC; for (TarjanSCC_iterator I = tarj_begin(&F), E = tarj_end(&F); I != E; ++I) ProcessSCC(*I, ModRefAfter, I.hasLoop()); From lattner at cs.uiuc.edu Sun Aug 31 15:03:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 15:03:03 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp MemoryDepAnalysis.cpp Message-ID: <200308312002.PAA02980@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: CallGraphSCCPass.cpp updated: 1.2 -> 1.3 MemoryDepAnalysis.cpp updated: 1.8 -> 1.9 --- Log message: Rename TarjanSCCIterator -> scc_iterator * Increases consistency with other iterators (e.g. df_iterator, po_iterator...) * It's shorter * We don't name classes by the implementation, we name it for the interface! --- Diffs of the changes: Index: llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp diff -u llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp:1.2 llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp:1.3 --- llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp:1.2 Sun Aug 31 14:35:16 2003 +++ llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp Sun Aug 31 15:01:57 2003 @@ -10,7 +10,7 @@ #include "llvm/CallGraphSCCPass.h" #include "llvm/Analysis/CallGraph.h" -#include "Support/TarjanSCCIterator.h" +#include "Support/SCCIterator.h" /// getAnalysisUsage - For this class, we declare that we require and preserve /// the call graph. If the derived class implements this method, it should @@ -23,7 +23,7 @@ bool CallGraphSCCPass::run(Module &M) { CallGraph &CG = getAnalysis(); bool Changed = false; - for (TarjanSCC_iterator I = tarj_begin(&CG), E = tarj_end(&CG); + for (scc_iterator I = scc_begin(&CG), E = scc_end(&CG); I != E; ++I) Changed = runOnSCC(*I); return Changed; Index: llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp diff -u llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.8 llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.9 --- llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp:1.8 Sun Aug 31 14:54:57 2003 +++ llvm/lib/Analysis/IPA/MemoryDepAnalysis.cpp Sun Aug 31 15:01:57 2003 @@ -18,7 +18,7 @@ #include "llvm/iOther.h" #include "llvm/Support/InstVisitor.h" #include "llvm/Support/CFG.h" -#include "Support/TarjanSCCIterator.h" +#include "Support/SCCIterator.h" #include "Support/Statistic.h" #include "Support/STLExtras.h" #include "Support/hash_map" @@ -208,7 +208,7 @@ } -/// Basic dependence gathering algorithm, using TarjanSCCIterator on CFG: +/// Basic dependence gathering algorithm, using scc_iterator on CFG: /// /// for every SCC S in the CFG in PostOrder on the SCC DAG /// { @@ -290,7 +290,7 @@ ModRefInfoBuilder builder(*funcGraph, *funcModRef, ModRefCurrent); for (std::vector::iterator BI = S.begin(), BE = S.end(); BI != BE; ++BI) - // Note: BBs in the SCC<> created by TarjanSCCIterator are in postorder. + // Note: BBs in the SCC<> created by scc_iterator are in postorder. for (BasicBlock::reverse_iterator II=(*BI)->rbegin(), IE=(*BI)->rend(); II != IE; ++II) builder.visit(*II); @@ -438,8 +438,7 @@ ModRefTable ModRefAfter; - for (TarjanSCC_iterator I = tarj_begin(&F), E = tarj_end(&F); - I != E; ++I) + for (scc_iterator I = scc_begin(&F), E = scc_end(&F); I != E; ++I) ProcessSCC(*I, ModRefAfter, I.hasLoop()); return true; From lattner at cs.uiuc.edu Sun Aug 31 15:03:11 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 15:03:11 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/PrintSCC.cpp Message-ID: <200308312002.PAA02971@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: PrintSCC.cpp updated: 1.6 -> 1.7 --- Log message: Rename TarjanSCCIterator -> scc_iterator * Increases consistency with other iterators (e.g. df_iterator, po_iterator...) * It's shorter * We don't name classes by the implementation, we name it for the interface! --- Diffs of the changes: Index: llvm/lib/Analysis/PrintSCC.cpp diff -u llvm/lib/Analysis/PrintSCC.cpp:1.6 llvm/lib/Analysis/PrintSCC.cpp:1.7 --- llvm/lib/Analysis/PrintSCC.cpp:1.6 Sun Aug 31 14:55:06 2003 +++ llvm/lib/Analysis/PrintSCC.cpp Sun Aug 31 15:01:56 2003 @@ -2,9 +2,10 @@ // // This file provides passes to print out SCCs in a CFG or a CallGraph. // Normally, you would not use these passes; instead, you would use the -// TarjanSCCIterator directly to enumerate SCCs and process them in some way. -// These passes serve three purposes: -// (1) As a reference for how to use the TarjanSCCIterator. +// scc_iterator directly to enumerate SCCs and process them in some way. These +// passes serve three purposes: +// +// (1) As a reference for how to use the scc_iterator. // (2) To print out the SCCs for a CFG or a CallGraph: // analyze -cfgscc to print the SCCs in each CFG of a module. // analyze -cfgscc -stats to print the #SCCs and the maximum SCC size. @@ -13,7 +14,7 @@ // and similarly: // analyze -callscc [-stats] [-debug] to print SCCs in the CallGraph // -// (3) To test the TarjanSCCIterator. +// (3) To test the scc_iterator. // //===----------------------------------------------------------------------===// @@ -21,7 +22,7 @@ #include "llvm/Module.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Support/CFG.h" -#include "Support/TarjanSCCIterator.h" +#include "Support/SCCIterator.h" namespace { struct CFGSCC : public FunctionPass { @@ -57,8 +58,8 @@ bool CFGSCC::runOnFunction(Function &F) { unsigned sccNum = 0; std::cout << "SCCs for Function " << F.getName() << " in PostOrder:"; - for (TarjanSCC_iterator SCCI = tarj_begin(&F), - E = tarj_end(&F); SCCI != E; ++SCCI) { + for (scc_iterator SCCI = scc_begin(&F), + E = scc_end(&F); SCCI != E; ++SCCI) { std::vector &nextSCC = *SCCI; std::cout << "\nSCC #" << ++sccNum << " : "; for (std::vector::const_iterator I = nextSCC.begin(), @@ -78,8 +79,8 @@ CallGraphNode* rootNode = getAnalysis().getRoot(); unsigned sccNum = 0; std::cout << "SCCs for the program in PostOrder:"; - for (TarjanSCC_iterator SCCI = tarj_begin(rootNode), - E = tarj_end(rootNode); SCCI != E; ++SCCI) { + for (scc_iterator SCCI = scc_begin(rootNode), + E = scc_end(rootNode); SCCI != E; ++SCCI) { const std::vector &nextSCC = *SCCI; std::cout << "\nSCC #" << ++sccNum << " : "; for (std::vector::const_iterator I = nextSCC.begin(), From lattner at cs.uiuc.edu Sun Aug 31 15:03:18 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 15:03:18 2003 Subject: [llvm-commits] CVS: llvm/include/Support/SCCIterator.h Message-ID: <200308312002.PAA02964@apoc.cs.uiuc.edu> Changes in directory llvm/include/Support: SCCIterator.h updated: 1.14 -> 1.15 --- Log message: Rename TarjanSCCIterator -> scc_iterator * Increases consistency with other iterators (e.g. df_iterator, po_iterator...) * It's shorter * We don't name classes by the implementation, we name it for the interface! --- Diffs of the changes: Index: llvm/include/Support/SCCIterator.h diff -u llvm/include/Support/SCCIterator.h:1.14 llvm/include/Support/SCCIterator.h:1.15 --- llvm/include/Support/SCCIterator.h:1.14 Sun Aug 31 14:55:31 2003 +++ llvm/include/Support/SCCIterator.h Sun Aug 31 15:01:53 2003 @@ -1,19 +1,18 @@ -//===-- Support/TarjanSCCIterator.h - Tarjan SCC iterator -------*- C++ -*-===// +//===-- Support/SCCIterator.h - SCC iterator --------------------*- C++ -*-===// // -// This builds on the Support/GraphTraits.h file to find the strongly -// connected components (SCCs) of a graph in O(N+E) time using -// Tarjan's DFS algorithm. +// This builds on the Support/GraphTraits.h file to find the strongly connected +// components (SCCs) of a graph in O(N+E) time using Tarjan's DFS algorithm. // -// The SCC iterator has the important property that if a node in SCC S1 -// has an edge to a node in SCC S2, then it visits S1 *after* S2. +// The SCC iterator has the important property that if a node in SCC S1 has an +// edge to a node in SCC S2, then it visits S1 *after* S2. // -// To visit S1 *before* S2, use the TarjanSCCIterator on the Inverse graph. +// To visit S1 *before* S2, use the scc_iterator on the Inverse graph. // (NOTE: This requires some simple wrappers and is not supported yet.) // //===----------------------------------------------------------------------===// -#ifndef SUPPORT_TARJANSCCITERATOR_H -#define SUPPORT_TARJANSCCITERATOR_H +#ifndef SUPPORT_SCCITERATOR_H +#define SUPPORT_SCCITERATOR_H #include "Support/GraphTraits.h" #include "Support/iterator" @@ -22,11 +21,11 @@ //===----------------------------------------------------------------------===// /// -/// TarjanSCC_iterator - Enumerate the SCCs of a directed graph, in +/// scc_iterator - Enumerate the SCCs of a directed graph, in /// reverse topological order of the SCC DAG. /// template > -class TarjanSCC_iterator +class scc_iterator : public forward_iterator, ptrdiff_t> { typedef typename GT::NodeType NodeType; typedef typename GT::ChildIteratorType ChildItTy; @@ -122,14 +121,14 @@ } } - inline TarjanSCC_iterator(NodeType *entryN) : visitNum(0) { + inline scc_iterator(NodeType *entryN) : visitNum(0) { DFSVisitOne(entryN); GetNextSCC(); } - inline TarjanSCC_iterator() { /* End is when DFS stack is empty */ } + inline scc_iterator() { /* End is when DFS stack is empty */ } public: - typedef TarjanSCC_iterator _Self; + typedef scc_iterator _Self; // Provide static "constructors"... static inline _Self begin(GraphT& G) { return _Self(GT::getEntryNode(G)); } @@ -180,15 +179,15 @@ }; -// Global constructor for the Tarjan SCC iterator. +// Global constructor for the SCC iterator. template -TarjanSCC_iterator tarj_begin(T G) { - return TarjanSCC_iterator::begin(G); +scc_iterator scc_begin(T G) { + return scc_iterator::begin(G); } template -TarjanSCC_iterator tarj_end(T G) { - return TarjanSCC_iterator::end(G); +scc_iterator scc_end(T G) { + return scc_iterator::end(G); } #endif From lattner at cs.uiuc.edu Sun Aug 31 15:38:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 15:38:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/CallGraph.cpp Message-ID: <200308312037.PAA03291@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: CallGraph.cpp updated: 1.23 -> 1.24 --- Log message: Replace M with F when refering to functions --- Diffs of the changes: Index: llvm/lib/Analysis/IPA/CallGraph.cpp diff -u llvm/lib/Analysis/IPA/CallGraph.cpp:1.23 llvm/lib/Analysis/IPA/CallGraph.cpp:1.24 --- llvm/lib/Analysis/IPA/CallGraph.cpp:1.23 Sun Nov 3 18:21:19 2002 +++ llvm/lib/Analysis/IPA/CallGraph.cpp Sun Aug 31 15:36:52 2003 @@ -61,27 +61,27 @@ // addToCallGraph - Add a function to the call graph, and link the node to all // of the functions that it calls. // -void CallGraph::addToCallGraph(Function *M) { - CallGraphNode *Node = getNodeFor(M); +void CallGraph::addToCallGraph(Function *F) { + CallGraphNode *Node = getNodeFor(F); // If this function has external linkage, - if (!M->hasInternalLinkage()) { + if (!F->hasInternalLinkage()) { ExternalNode->addCalledFunction(Node); // Found the entry point? - if (M->getName() == "main") { + if (F->getName() == "main") { if (Root) Root = ExternalNode; // Found multiple external mains? Don't pick one. else Root = Node; // Found a main, keep track of it! } - } else if (M->isExternal()) { // Not defined in this xlation unit? + } else if (F->isExternal()) { // Not defined in this xlation unit? Node->addCalledFunction(ExternalNode); // It could call anything... } // Loop over all of the users of the function... looking for callers... // - for (Value::use_iterator I = M->use_begin(), E = M->use_end(); I != E; ++I) { + for (Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E; ++I) { User *U = *I; if (CallInst *CI = dyn_cast(U)) getNodeFor(CI->getParent()->getParent())->addCalledFunction(Node); @@ -92,7 +92,7 @@ } // Look for an indirect function call... - for (Function::iterator BB = M->begin(), BBE = M->end(); BB != BBE; ++BB) + for (Function::iterator BB = F->begin(), BBE = F->end(); BB != BBE; ++BB) for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE; ++II){ Instruction &I = *II; @@ -174,11 +174,11 @@ Function *CallGraph::removeFunctionFromModule(CallGraphNode *CGN) { assert(CGN->CalledFunctions.empty() && "Cannot remove function from call " "graph if it references other functions!"); - Function *M = CGN->getFunction(); // Get the function for the call graph node + Function *F = CGN->getFunction(); // Get the function for the call graph node delete CGN; // Delete the call graph node for this func - FunctionMap.erase(M); // Remove the call graph node from the map + FunctionMap.erase(F); // Remove the call graph node from the map - Mod->getFunctionList().remove(M); - return M; + Mod->getFunctionList().remove(F); + return F; } From lattner at cs.uiuc.edu Sun Aug 31 16:06:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 16:06:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/TailDup/2003-08-31-UnreachableBlocks.ll Message-ID: <200308312105.QAA06734@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/TailDup: 2003-08-31-UnreachableBlocks.ll added (r1.1) --- Log message: New testcase --- Diffs of the changes: Index: llvm/test/Regression/Transforms/TailDup/2003-08-31-UnreachableBlocks.ll diff -c /dev/null llvm/test/Regression/Transforms/TailDup/2003-08-31-UnreachableBlocks.ll:1.1 *** /dev/null Sun Aug 31 16:05:49 2003 --- llvm/test/Regression/Transforms/TailDup/2003-08-31-UnreachableBlocks.ll Sun Aug 31 16:05:39 2003 *************** *** 0 **** --- 1,20 ---- + ; RUN: llvm-as < %s | opt -tailduplicate -disable-output + + int %foo() { + entry: + br label %return.i + + after_ret.i: + br label %return.i + + return.i: + %tmp.3 = cast int* null to int + br label %return.i1 + + after_ret.i1: + br label %return.i1 + + return.i1: + %tmp.8 = sub int %tmp.3, 0 + ret int 0 + } From lattner at cs.uiuc.edu Sun Aug 31 16:18:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 16:18:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/TailDuplication.cpp Message-ID: <200308312117.QAA07617@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: TailDuplication.cpp updated: 1.7 -> 1.8 --- Log message: Fix bug: TailDuplicate/2003-08-31-UnreachableBlocks.ll --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/TailDuplication.cpp diff -u llvm/lib/Transforms/Scalar/TailDuplication.cpp:1.7 llvm/lib/Transforms/Scalar/TailDuplication.cpp:1.8 --- llvm/lib/Transforms/Scalar/TailDuplication.cpp:1.7 Sat Aug 23 15:08:30 2003 +++ llvm/lib/Transforms/Scalar/TailDuplication.cpp Sun Aug 31 16:17:44 2003 @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Scalar.h" +#include "llvm/Constant.h" #include "llvm/Function.h" #include "llvm/iPHINode.h" #include "llvm/iTerminators.h" @@ -268,8 +269,10 @@ ValueHolder &BBVal = ValueMap[BB]; if (BBVal) return BBVal; // Value already computed for this block? - assert(pred_begin(BB) != pred_end(BB) && - "Propagating PHI nodes to unreachable blocks?"); + // If this block has no predecessors, then it must be unreachable, thus, it + // doesn't matter which value we use. + if (pred_begin(BB) == pred_end(BB)) + return BBVal = Constant::getNullValue(OrigVal->getType()); // If there is no value already available in this basic block, we need to // either reuse a value from an incoming, dominating, basic block, or we need From lattner at cs.uiuc.edu Sun Aug 31 16:47:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 16:47:01 2003 Subject: [llvm-commits] CVS: llvm/tools/gccas/gccas.cpp Message-ID: <200308312146.QAA24246@apoc.cs.uiuc.edu> Changes in directory llvm/tools/gccas: gccas.cpp updated: 1.68 -> 1.69 --- Log message: * move the dead-type-eliminate passes to the end, where they are more useful * add prune-eh and inlining passes * other minor pass reorganizations --- Diffs of the changes: Index: llvm/tools/gccas/gccas.cpp diff -u llvm/tools/gccas/gccas.cpp:1.68 llvm/tools/gccas/gccas.cpp:1.69 --- llvm/tools/gccas/gccas.cpp:1.68 Thu Aug 7 16:30:12 2003 +++ llvm/tools/gccas/gccas.cpp Sun Aug 31 16:45:55 2003 @@ -62,17 +62,20 @@ void AddConfiguredTransformationPasses(PassManager &PM) { PM.add(createVerifierPass()); // Verify that input is correct addPass(PM, createFunctionResolvingPass()); // Resolve (...) functions - addPass(PM, createGlobalDCEPass()); // Kill unused uinit g-vars - addPass(PM, createDeadTypeEliminationPass()); // Eliminate dead types - addPass(PM, createConstantMergePass()); // Merge dup global constants addPass(PM, createRaiseAllocationsPass()); // call %malloc -> malloc inst + addPass(PM, createGlobalDCEPass()); // Remove unused globals + addPass(PM, createPruneEHPass()); // Remove dead EH info + addPass(PM, createFunctionInliningPass()); // Inline small functions + addPass(PM, createInstructionCombiningPass()); // Cleanup code for raise addPass(PM, createRaisePointerReferencesPass());// Recover type information addPass(PM, createTailDuplicationPass()); // Simplify cfg by copying code addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs - addPass(PM, createInstructionCombiningPass()); // Combine silly seq's addPass(PM, createScalarReplAggregatesPass()); // Break up aggregate allocas addPass(PM, createPromoteMemoryToRegister()); // Promote alloca's to regs + addPass(PM, createInstructionCombiningPass()); // Combine silly seq's + + addPass(PM, createIndVarSimplifyPass()); // Simplify indvars addPass(PM, createReassociatePass()); // Reassociate expressions addPass(PM, createInstructionCombiningPass()); // Combine silly seq's @@ -87,6 +90,8 @@ addPass(PM, createInstructionCombiningPass()); addPass(PM, createAggressiveDCEPass()); // SSA based 'Aggressive DCE' addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs + addPass(PM, createDeadTypeEliminationPass()); // Eliminate dead types + addPass(PM, createConstantMergePass()); // Merge dup global constants } From lattner at cs.uiuc.edu Sun Aug 31 16:48:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 16:48:01 2003 Subject: [llvm-commits] CVS: llvm/tools/gccas/gccas.cpp Message-ID: <200308312147.QAA24477@apoc.cs.uiuc.edu> Changes in directory llvm/tools/gccas: gccas.cpp updated: 1.69 -> 1.70 --- Log message: Remove the -stopAfterNPasses option, which has been long obsoleted by bugpoint --- Diffs of the changes: Index: llvm/tools/gccas/gccas.cpp diff -u llvm/tools/gccas/gccas.cpp:1.69 llvm/tools/gccas/gccas.cpp:1.70 --- llvm/tools/gccas/gccas.cpp:1.69 Sun Aug 31 16:45:55 2003 +++ llvm/tools/gccas/gccas.cpp Sun Aug 31 16:47:24 2003 @@ -30,32 +30,17 @@ OutputFilename("o", cl::desc("Override output filename"), cl::value_desc("filename")); - cl::opt - RunNPasses("stopAfterNPasses", - cl::desc("Only run the first N passes of gccas"), cl::Hidden, - cl::value_desc("# passes")); - cl::opt Verify("verify", cl::desc("Verify each pass result")); } static inline void addPass(PassManager &PM, Pass *P) { - static int NumPassesCreated = 0; + // Add the pass to the pass manager... + PM.add(P); - // If we haven't already created the number of passes that was requested... - if (RunNPasses == 0 || RunNPasses > NumPassesCreated) { - // Add the pass to the pass manager... - PM.add(P); - - // If we are verifying all of the intermediate steps, add the verifier... - if (Verify) PM.add(createVerifierPass()); - - // Keep track of how many passes we made for -stopAfterNPasses - ++NumPassesCreated; - } else { - delete P; // We don't want this pass to run, just delete it now - } + // If we are verifying all of the intermediate steps, add the verifier... + if (Verify) PM.add(createVerifierPass()); } From lattner at cs.uiuc.edu Sun Aug 31 22:15:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 22:15:00 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/IPO.h Scalar.h Message-ID: <200309010314.WAA29917@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: IPO.h updated: 1.19 -> 1.20 Scalar.h updated: 1.20 -> 1.21 --- Log message: Change the RaiseAllocations pass from being a BasicBlockPass to being a Pass --- Diffs of the changes: Index: llvm/include/llvm/Transforms/IPO.h diff -u llvm/include/llvm/Transforms/IPO.h:1.19 llvm/include/llvm/Transforms/IPO.h:1.20 --- llvm/include/llvm/Transforms/IPO.h:1.19 Sun Aug 31 11:30:25 2003 +++ llvm/include/llvm/Transforms/IPO.h Sun Aug 31 22:14:00 2003 @@ -22,6 +22,13 @@ //===----------------------------------------------------------------------===// +// createRaiseAllocationsPass - Return a new pass that transforms malloc and +// free function calls into malloc and free instructions. +// +Pass *createRaiseAllocationsPass(); + + +//===----------------------------------------------------------------------===// // createDeadTypeEliminationPass - Return a new pass that eliminates symbol // table entries for types that are never used. // Index: llvm/include/llvm/Transforms/Scalar.h diff -u llvm/include/llvm/Transforms/Scalar.h:1.20 llvm/include/llvm/Transforms/Scalar.h:1.21 --- llvm/include/llvm/Transforms/Scalar.h:1.20 Thu Aug 14 01:09:28 2003 +++ llvm/include/llvm/Transforms/Scalar.h Sun Aug 31 22:14:00 2003 @@ -235,11 +235,10 @@ //===----------------------------------------------------------------------===// -// These two passes convert malloc and free instructions to and from %malloc & -// %free function calls. +// This pass convert malloc and free instructions to %malloc & %free function +// calls. // FunctionPass *createLowerAllocationsPass(); -Pass *createRaiseAllocationsPass(); //===----------------------------------------------------------------------===// // This pass converts SwitchInst instructions into a sequence of chained binary From lattner at cs.uiuc.edu Sun Aug 31 22:16:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Aug 31 22:16:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/RaiseAllocations.cpp Message-ID: <200309010315.WAA29931@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: RaiseAllocations.cpp updated: 1.16 -> 1.17 --- Log message: Change the RaiseAllocations pass to be a Pass instead of a BasicBlock pass. This makes it more efficient: it doesn't have to scan the whole program, so it performs work proportional to the number of malloc/free calls in the program, not the size of the program. --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/RaiseAllocations.cpp diff -u llvm/lib/Transforms/IPO/RaiseAllocations.cpp:1.16 llvm/lib/Transforms/IPO/RaiseAllocations.cpp:1.17 --- llvm/lib/Transforms/IPO/RaiseAllocations.cpp:1.16 Mon Aug 18 09:33:38 2003 +++ llvm/lib/Transforms/IPO/RaiseAllocations.cpp Sun Aug 31 22:14:56 2003 @@ -5,13 +5,13 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/IPO.h" #include "llvm/Module.h" #include "llvm/DerivedTypes.h" #include "llvm/iMemory.h" #include "llvm/iOther.h" #include "llvm/Pass.h" +#include "llvm/Support/CallSite.h" #include "Support/Statistic.h" namespace { @@ -20,7 +20,7 @@ // RaiseAllocations - Turn %malloc and %free calls into the appropriate // instruction. // - class RaiseAllocations : public BasicBlockPass { + class RaiseAllocations : public Pass { Function *MallocFunc; // Functions in the module we are processing Function *FreeFunc; // Initialized by doPassInitializationVirt public: @@ -29,12 +29,11 @@ // doPassInitialization - For the raise allocations pass, this finds a // declaration for malloc and free if they exist. // - bool doInitialization(Module &M); + void doInitialization(Module &M); - // runOnBasicBlock - This method does the actual work of converting - // instructions over, assuming that the pass has already been initialized. + // run - This method does the actual work of converting instructions over. // - bool runOnBasicBlock(BasicBlock &BB); + bool run(Module &M); }; RegisterOpt @@ -48,15 +47,15 @@ } -bool RaiseAllocations::doInitialization(Module &M) { - // If the module has a symbol table, they might be referring to the malloc - // and free functions. If this is the case, grab the method pointers that - // the module is using. - // - // Lookup %malloc and %free in the symbol table, for later use. If they - // don't exist, or are not external, we do not worry about converting calls - // to that function into the appropriate instruction. - // +// If the module has a symbol table, they might be referring to the malloc and +// free functions. If this is the case, grab the method pointers that the +// module is using. +// +// Lookup %malloc and %free in the symbol table, for later use. If they don't +// exist, or are not external, we do not worry about converting calls to that +// function into the appropriate instruction. +// +void RaiseAllocations::doInitialization(Module &M) { const FunctionType *MallocType = // Get the type for malloc FunctionType::get(PointerType::get(Type::SByteTy), std::vector(1, Type::ULongTy), false); @@ -100,52 +99,74 @@ FreeFunc = M.getFunction("free", FreeType); } - // Don't mess with locally defined versions of these functions... if (MallocFunc && !MallocFunc->isExternal()) MallocFunc = 0; if (FreeFunc && !FreeFunc->isExternal()) FreeFunc = 0; - return false; } -// runOnBasicBlock - Process a basic block, fixing it up... +// run - Transform calls into instructions... // -bool RaiseAllocations::runOnBasicBlock(BasicBlock &BB) { +bool RaiseAllocations::run(Module &M) { + // Find the malloc/free prototypes... + doInitialization(M); + bool Changed = false; - BasicBlock::InstListType &BIL = BB.getInstList(); - for (BasicBlock::iterator BI = BB.begin(); BI != BB.end(); ++BI) { - Instruction *I = BI; + // First, process all of the malloc calls... + if (MallocFunc) { + std::vector Users(MallocFunc->use_begin(), MallocFunc->use_end()); + while (!Users.empty()) { + if (Instruction *I = dyn_cast(Users.back())) { + CallSite CS = CallSite::get(I); + if (CS.getInstruction() && CS.getCalledFunction() == MallocFunc && + CS.arg_begin() != CS.arg_end()) { + Value *Source = *CS.arg_begin(); + + // If no prototype was provided for malloc, we may need to cast the + // source size. + if (Source->getType() != Type::UIntTy) + Source = new CastInst(Source, Type::UIntTy, "MallocAmtCast", I); + + std::string Name(I->getName()); I->setName(""); + MallocInst *MI = new MallocInst(Type::SByteTy, Source, Name, I); + I->replaceAllUsesWith(MI); + MI->getParent()->getInstList().erase(I); + Changed = true; + ++NumRaised; + } + } + + Users.pop_back(); + } + } - if (CallInst *CI = dyn_cast(I)) { - if (CI->getCalledValue() == MallocFunc) { // Replace call to malloc? - Value *Source = CI->getOperand(1); - - // If no prototype was provided for malloc, we may need to cast the - // source size. - if (Source->getType() != Type::UIntTy) - Source = new CastInst(Source, Type::UIntTy, "MallocAmtCast", BI); - - std::string Name(CI->getName()); CI->setName(""); - BI = new MallocInst(Type::SByteTy, Source, Name, BI); - CI->replaceAllUsesWith(BI); - BIL.erase(I); - Changed = true; - ++NumRaised; - } else if (CI->getCalledValue() == FreeFunc) { // Replace call to free? - // If no prototype was provided for free, we may need to cast the - // source pointer. This should be really uncommon, but it's necessary - // just in case we are dealing with wierd code like this: - // free((long)ptr); - // - Value *Source = CI->getOperand(1); - if (!isa(Source->getType())) - Source = new CastInst(Source, PointerType::get(Type::SByteTy), - "FreePtrCast", BI); - BI = new FreeInst(Source, BI); - BIL.erase(I); - Changed = true; - ++NumRaised; + // Next, process all free calls... + if (FreeFunc) { + std::vector Users(FreeFunc->use_begin(), FreeFunc->use_end()); + + while (!Users.empty()) { + if (Instruction *I = dyn_cast(Users.back())) { + CallSite CS = CallSite::get(I); + if (CS.getInstruction() && CS.getCalledFunction() == FreeFunc && + CS.arg_begin() != CS.arg_end()) { + + // If no prototype was provided for free, we may need to cast the + // source pointer. This should be really uncommon, but it's necessary + // just in case we are dealing with wierd code like this: + // free((long)ptr); + // + Value *Source = *CS.arg_begin(); + if (!isa(Source->getType())) + Source = new CastInst(Source, PointerType::get(Type::SByteTy), + "FreePtrCast", I); + new FreeInst(Source, I); + I->getParent()->getInstList().erase(I); + Changed = true; + ++NumRaised; + } } + + Users.pop_back(); } }