From lattner at cs.uiuc.edu Mon Nov 14 00:54:45 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 14 Nov 2005 00:54:45 -0600 Subject: [llvm-commits] CVS: llvm/autoconf/configure.ac Message-ID: <200511140654.AAA07233@zion.cs.uiuc.edu> Changes in directory llvm/autoconf: configure.ac updated: 1.198 -> 1.199 --- Log message: add some stuff for mstats on darwin --- Diffs of the changes: (+2 -1) configure.ac | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/autoconf/configure.ac diff -u llvm/autoconf/configure.ac:1.198 llvm/autoconf/configure.ac:1.199 --- llvm/autoconf/configure.ac:1.198 Tue Nov 8 15:13:01 2005 +++ llvm/autoconf/configure.ac Mon Nov 14 00:54:33 2005 @@ -486,6 +486,7 @@ AC_CHECK_HEADERS([dlfcn.h execinfo.h fcntl.h inttypes.h limits.h link.h]) AC_CHECK_HEADERS([malloc.h signal.h stdint.h unistd.h utime.h windows.h]) AC_CHECK_HEADERS([sys/mman.h sys/param.h sys/resource.h sys/time.h sys/types.h]) +AC_CHECK_HEADERS([malloc/malloc.h]) AC_CHECK_HEADERS([rw/stdex/hash_map.h rw/stdex/hash_set.h]) if test "$ENABLE_THREADS" -eq 1 ; then AC_CHECK_HEADERS(pthread.h) @@ -515,7 +516,7 @@ AC_CHECK_FUNCS([backtrace getcwd getpagesize getrusage gettimeofday ]) AC_CHECK_FUNCS([isatty mkdtemp mkstemp mktemp ]) AC_CHECK_FUNCS([realpath sbrk setrlimit strdup strerror strerror_r ]) -AC_CHECK_FUNCS([strtoll strtoq sysconf]) +AC_CHECK_FUNCS([strtoll strtoq sysconf mstats ]) AC_C_PRINTF_A AC_FUNC_ALLOCA AC_FUNC_RAND48 From lattner at cs.uiuc.edu Mon Nov 14 00:57:22 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 14 Nov 2005 00:57:22 -0600 Subject: [llvm-commits] CVS: llvm/configure Message-ID: <200511140657.AAA07454@zion.cs.uiuc.edu> Changes in directory llvm: configure updated: 1.201 -> 1.202 --- Log message: regenerate --- Diffs of the changes: (+152 -1) configure | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 152 insertions(+), 1 deletion(-) Index: llvm/configure diff -u llvm/configure:1.201 llvm/configure:1.202 --- llvm/configure:1.201 Tue Nov 8 15:12:58 2005 +++ llvm/configure Mon Nov 14 00:57:11 2005 @@ -26802,6 +26802,156 @@ done +for ac_header in malloc/malloc.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ----------------------------------- ## +## Report this to llvmbugs at cs.uiuc.edu ## +## ----------------------------------- ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + for ac_header in rw/stdex/hash_map.h rw/stdex/hash_set.h do @@ -27897,7 +28047,8 @@ -for ac_func in strtoll strtoq sysconf + +for ac_func in strtoll strtoq sysconf mstats do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 From lattner at cs.uiuc.edu Mon Nov 14 00:57:45 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 14 Nov 2005 00:57:45 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Config/config.h.in Message-ID: <200511140657.AAA07474@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Config: config.h.in updated: 1.57 -> 1.58 --- Log message: regenerate --- Diffs of the changes: (+6 -0) config.h.in | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/include/llvm/Config/config.h.in diff -u llvm/include/llvm/Config/config.h.in:1.57 llvm/include/llvm/Config/config.h.in:1.58 --- llvm/include/llvm/Config/config.h.in:1.57 Wed Aug 24 05:07:21 2005 +++ llvm/include/llvm/Config/config.h.in Mon Nov 14 00:57:34 2005 @@ -185,6 +185,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_MALLOC_H + /* Define to 1 if you have the `memcpy' function. */ #undef HAVE_MEMCPY @@ -213,6 +216,9 @@ /* Define if mmap() can map files into memory */ #undef HAVE_MMAP_FILE +/* Define to 1 if you have the `mstats' function. */ +#undef HAVE_MSTATS + /* define if the compiler implements namespaces */ #undef HAVE_NAMESPACES From lattner at cs.uiuc.edu Mon Nov 14 01:00:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 14 Nov 2005 01:00:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Process.inc Message-ID: <200511140700.BAA07661@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Process.inc updated: 1.11 -> 1.12 --- Log message: Teach -track-memory to work on darwin. Looking at sbrk doesn't work because the default allocator uses mmap. --- Diffs of the changes: (+12 -10) Process.inc | 22 ++++++++++++---------- 1 files changed, 12 insertions(+), 10 deletions(-) Index: llvm/lib/System/Unix/Process.inc diff -u llvm/lib/System/Unix/Process.inc:1.11 llvm/lib/System/Unix/Process.inc:1.12 --- llvm/lib/System/Unix/Process.inc:1.11 Thu May 5 17:33:06 2005 +++ llvm/lib/System/Unix/Process.inc Mon Nov 14 01:00:29 2005 @@ -21,6 +21,9 @@ #ifdef HAVE_MALLOC_H #include #endif +#ifdef HAVE_MALLOC_MALLOC_H +#include +#endif //===----------------------------------------------------------------------===// //=== WARNING: Implementation here must contain only generic UNIX code that @@ -43,23 +46,20 @@ return static_cast(page_size); } -#if defined(HAVE_SBRK) -static char* som = reinterpret_cast(::sbrk(0)); -#endif - -size_t -Process::GetMallocUsage() -{ +size_t Process::GetMallocUsage() { #if defined(HAVE_MALLINFO) struct mallinfo mi; mi = ::mallinfo(); return mi.uordblks; +#elif defined(HAVE_MSTATS) && defined(HAVE_MALLOC_MALLOC_H) + return mstats().bytes_used; // darwin #elif defined(HAVE_SBRK) // Note this is only an approximation and more closely resembles // the value returned by mallinfo in the arena field. - char * eom = (char*) sbrk(0); - if (eom != ((char*)-1) && som != ((char*)-1)) - return eom - som; + static char *StartOfMemory = reinterpret_cast(::sbrk(0)); + char *EndOfMemory = (char*)sbrk(0); + if (EndOfMemory != ((char*)-1) && StartOfMemory != ((char*)-1)) + return EndOfMemory - StartOfMemory; else return 0; #else @@ -74,6 +74,8 @@ #if defined(HAVE_MALLINFO) struct mallinfo mi = ::mallinfo(); return mi.uordblks + mi.hblkhd; +#elif defined(HAVE_MSTATS) && defined(HAVE_MALLOC_MALLOC_H) + return mstats().bytes_total; // darwin #elif defined(HAVE_GETRUSAGE) struct rusage usage; ::getrusage(RUSAGE_SELF, &usage); From lattner at cs.uiuc.edu Mon Nov 14 01:24:13 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 14 Nov 2005 01:24:13 -0600 Subject: [llvm-commits] CVS: llvm/autoconf/configure.ac Message-ID: <200511140724.BAA08164@zion.cs.uiuc.edu> Changes in directory llvm/autoconf: configure.ac updated: 1.199 -> 1.200 --- Log message: add malloc_zone_statistics, remove mstats --- Diffs of the changes: (+1 -1) configure.ac | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/autoconf/configure.ac diff -u llvm/autoconf/configure.ac:1.199 llvm/autoconf/configure.ac:1.200 --- llvm/autoconf/configure.ac:1.199 Mon Nov 14 00:54:33 2005 +++ llvm/autoconf/configure.ac Mon Nov 14 01:24:01 2005 @@ -516,7 +516,7 @@ AC_CHECK_FUNCS([backtrace getcwd getpagesize getrusage gettimeofday ]) AC_CHECK_FUNCS([isatty mkdtemp mkstemp mktemp ]) AC_CHECK_FUNCS([realpath sbrk setrlimit strdup strerror strerror_r ]) -AC_CHECK_FUNCS([strtoll strtoq sysconf mstats ]) +AC_CHECK_FUNCS([strtoll strtoq sysconf malloc_zone_statistics ]) AC_C_PRINTF_A AC_FUNC_ALLOCA AC_FUNC_RAND48 From lattner at cs.uiuc.edu Mon Nov 14 01:24:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 14 Nov 2005 01:24:29 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Config/config.h.in Message-ID: <200511140724.BAA08173@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Config: config.h.in updated: 1.58 -> 1.59 --- Log message: add malloc_zone_statistics, remove mstats --- Diffs of the changes: (+3 -3) config.h.in | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/include/llvm/Config/config.h.in diff -u llvm/include/llvm/Config/config.h.in:1.58 llvm/include/llvm/Config/config.h.in:1.59 --- llvm/include/llvm/Config/config.h.in:1.58 Mon Nov 14 00:57:34 2005 +++ llvm/include/llvm/Config/config.h.in Mon Nov 14 01:24:17 2005 @@ -188,6 +188,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_MALLOC_H +/* Define to 1 if you have the `malloc_zone_statistics' function. */ +#undef HAVE_MALLOC_ZONE_STATISTICS + /* Define to 1 if you have the `memcpy' function. */ #undef HAVE_MEMCPY @@ -216,9 +219,6 @@ /* Define if mmap() can map files into memory */ #undef HAVE_MMAP_FILE -/* Define to 1 if you have the `mstats' function. */ -#undef HAVE_MSTATS - /* define if the compiler implements namespaces */ #undef HAVE_NAMESPACES From lattner at cs.uiuc.edu Mon Nov 14 01:26:01 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 14 Nov 2005 01:26:01 -0600 Subject: [llvm-commits] CVS: llvm/configure Message-ID: <200511140726.BAA08261@zion.cs.uiuc.edu> Changes in directory llvm: configure updated: 1.202 -> 1.203 --- Log message: regenearte --- Diffs of the changes: (+1 -1) configure | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/configure diff -u llvm/configure:1.202 llvm/configure:1.203 --- llvm/configure:1.202 Mon Nov 14 00:57:11 2005 +++ llvm/configure Mon Nov 14 01:25:50 2005 @@ -28048,7 +28048,7 @@ -for ac_func in strtoll strtoq sysconf mstats +for ac_func in strtoll strtoq sysconf malloc_zone_statistics do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 From lattner at cs.uiuc.edu Mon Nov 14 01:28:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 14 Nov 2005 01:28:08 -0600 Subject: [llvm-commits] CVS: llvm/lib/System/Unix/Process.inc Message-ID: <200511140728.BAA08342@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Process.inc updated: 1.12 -> 1.13 --- Log message: instead of using mstats, use malloc_zone_statistics which returns numbers that actually make sense. --- Diffs of the changes: (+8 -4) Process.inc | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-) Index: llvm/lib/System/Unix/Process.inc diff -u llvm/lib/System/Unix/Process.inc:1.12 llvm/lib/System/Unix/Process.inc:1.13 --- llvm/lib/System/Unix/Process.inc:1.12 Mon Nov 14 01:00:29 2005 +++ llvm/lib/System/Unix/Process.inc Mon Nov 14 01:27:56 2005 @@ -51,8 +51,10 @@ struct mallinfo mi; mi = ::mallinfo(); return mi.uordblks; -#elif defined(HAVE_MSTATS) && defined(HAVE_MALLOC_MALLOC_H) - return mstats().bytes_used; // darwin +#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H) + malloc_statistics_t Stats; + malloc_zone_statistics(malloc_default_zone(), &Stats); + return Stats.size_in_use; // darwin #elif defined(HAVE_SBRK) // Note this is only an approximation and more closely resembles // the value returned by mallinfo in the arena field. @@ -74,8 +76,10 @@ #if defined(HAVE_MALLINFO) struct mallinfo mi = ::mallinfo(); return mi.uordblks + mi.hblkhd; -#elif defined(HAVE_MSTATS) && defined(HAVE_MALLOC_MALLOC_H) - return mstats().bytes_total; // darwin +#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H) + malloc_statistics_t Stats; + malloc_zone_statistics(malloc_default_zone(), &Stats); + return Stats.size_allocated; // darwin #elif defined(HAVE_GETRUSAGE) struct rusage usage; ::getrusage(RUSAGE_SELF, &usage); From brukman at cs.uiuc.edu Mon Nov 14 11:59:09 2005 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Mon, 14 Nov 2005 11:59:09 -0600 Subject: [llvm-commits] CVS: llvm-www/www-index.html Message-ID: <200511141759.LAA14429@zion.cs.uiuc.edu> Changes in directory llvm-www: www-index.html updated: 1.124 -> 1.125 --- Log message: Fix broken link to list of developers (it's now a CGI script, not static page) --- Diffs of the changes: (+1 -1) www-index.html | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-www/www-index.html diff -u llvm-www/www-index.html:1.124 llvm-www/www-index.html:1.125 --- llvm-www/www-index.html:1.124 Tue Nov 8 14:30:03 2005 +++ llvm-www/www-index.html Mon Nov 14 11:58:57 2005 @@ -70,7 +70,7 @@ href="http://www.uiuc.edu/">University of Illinois, Urbana-Champaign. Since the first public release, LLVM has grown to include contributions from several -other people! We welcome external contributions, +other people! We welcome external contributions, so please send e-mail to llvmdev at cs.uiuc.edu if you are interested in contributing code to the LLVM infrastructure.

From lattner at cs.uiuc.edu Mon Nov 14 12:52:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 14 Nov 2005 12:52:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Message-ID: <200511141852.MAA24290@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.106 -> 1.107 --- Log message: Teach the PPC asmwriter to honor globals with explicit section requests. --- Diffs of the changes: (+32 -22) PPCAsmPrinter.cpp | 54 ++++++++++++++++++++++++++++++++---------------------- 1 files changed, 32 insertions(+), 22 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.106 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.107 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.106 Thu Nov 10 15:59:25 2005 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Mon Nov 14 12:52:46 2005 @@ -43,9 +43,11 @@ namespace { Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); - struct PPCAsmPrinter : public AsmPrinter { + class PPCAsmPrinter : public AsmPrinter { + std::string CurSection; + public: std::set FnStubs, GVStubs, LinkOnceStubs; - + PPCAsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM), FunctionNumber(0) {} @@ -61,6 +63,25 @@ return static_cast(TM); } + /// SwitchSection - Switch to the specified section of the executable if we + /// are not already in it! + /// + void SwitchSection(const char *NewSection, const GlobalValue *GV) { + std::string NS; + + if (GV && GV->hasSection()) + NS = ".section " + GV->getSection(); + else + NS = NewSection; + + + if (CurSection != NS) { + CurSection = NS; + if (!CurSection.empty()) + O << "\t" << CurSection << "\n"; + } + } + unsigned enumRegToMachineReg(unsigned enumReg) { switch (enumReg) { default: assert(0 && "Unhandled register!"); break; @@ -227,18 +248,6 @@ }; } // end of anonymous namespace -// SwitchSection - Switch to the specified section of the executable if we are -// not already in it! -// -static void SwitchSection(std::ostream &OS, std::string &CurSection, - const char *NewSection) { - if (CurSection != NewSection) { - CurSection = NewSection; - if (!CurSection.empty()) - OS << "\t" << NewSection << "\n"; - } -} - /// createDarwinAsmPrinterPass - Returns a pass that prints the PPC assembly /// code for a MachineFunction to the given output stream, in a format that the /// Darwin assembler can deal with. @@ -387,9 +396,10 @@ printConstantPool(MF.getConstantPool()); // Print out labels for the function. - O << "\t.text\n"; + const Function *F = MF.getFunction(); + SwitchSection(".text", F); emitAlignment(4); - if (!MF.getFunction()->hasInternalLinkage()) + if (!F->hasInternalLinkage()) O << "\t.globl\t" << CurrentFnName << "\n"; O << CurrentFnName << ":\n"; @@ -444,6 +454,7 @@ bool DarwinAsmPrinter::doInitialization(Module &M) { if (TM.getSubtarget().isGigaProcessor()) O << "\t.machine ppc970\n"; + SwitchSection("", 0); AsmPrinter::doInitialization(M); // Darwin wants symbols to be quoted if they have complex names. @@ -453,7 +464,6 @@ bool DarwinAsmPrinter::doFinalization(Module &M) { const TargetData &TD = TM.getTargetData(); - std::string CurSection; // Print out module-level global variables here. for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) @@ -467,7 +477,7 @@ if (C->isNullValue() && /* FIXME: Verify correct */ (I->hasInternalLinkage() || I->hasWeakLinkage() || I->hasLinkOnceLinkage())) { - SwitchSection(O, CurSection, ".data"); + SwitchSection(".data", I); if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. if (I->hasInternalLinkage()) O << ".lcomm " << name << "," << Size << "," << Align; @@ -495,10 +505,10 @@ O << "\t.globl " << name << "\n"; // FALL THROUGH case GlobalValue::InternalLinkage: - SwitchSection(O, CurSection, ".data"); + SwitchSection(".data", I); break; - case GlobalValue::GhostLinkage: - std::cerr << "Error: unmaterialized (GhostLinkage) function in asm!"; + default: + std::cerr << "Unknown linkage type!"; abort(); } @@ -649,8 +659,8 @@ } bool AIXAsmPrinter::doInitialization(Module &M) { + SwitchSection("", 0); const TargetData &TD = TM.getTargetData(); - std::string CurSection; O << "\t.machine \"ppc64\"\n" << "\t.toc\n" From lattner at cs.uiuc.edu Mon Nov 14 12:59:54 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 14 Nov 2005 12:59:54 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/AsmPrinter.h Message-ID: <200511141859.MAA24374@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: AsmPrinter.h updated: 1.14 -> 1.15 --- Log message: Teach emitAlignment to handle explicit alignment requests by globals. --- Diffs of the changes: (+3 -2) AsmPrinter.h | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/include/llvm/CodeGen/AsmPrinter.h diff -u llvm/include/llvm/CodeGen/AsmPrinter.h:1.14 llvm/include/llvm/CodeGen/AsmPrinter.h:1.15 --- llvm/include/llvm/CodeGen/AsmPrinter.h:1.14 Thu Nov 10 12:05:57 2005 +++ llvm/include/llvm/CodeGen/AsmPrinter.h Mon Nov 14 12:59:42 2005 @@ -137,8 +137,9 @@ /// emitAlignment - Emit an alignment directive to the specified power of /// two boundary. For example, if you pass in 3 here, you will get an 8 - /// byte alignment. - void emitAlignment(unsigned NumBits) const; + /// byte alignment. If a global value is specified, and if that global has + /// an explicit alignment requested, it will override the alignment request. + void emitAlignment(unsigned NumBits, const GlobalValue *GV = 0) const; /// emitZeros - Emit a block of zeros. /// From lattner at cs.uiuc.edu Mon Nov 14 13:00:17 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 14 Nov 2005 13:00:17 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200511141900.NAA24437@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.23 -> 1.24 --- Log message: Teach emitAlignment to handle explicit alignment requests by globals. --- Diffs of the changes: (+3 -1) AsmPrinter.cpp | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.23 llvm/lib/CodeGen/AsmPrinter.cpp:1.24 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.23 Thu Nov 10 12:36:17 2005 +++ llvm/lib/CodeGen/AsmPrinter.cpp Mon Nov 14 13:00:06 2005 @@ -35,7 +35,9 @@ } // emitAlignment - Emit an alignment directive to the specified power of two. -void AsmPrinter::emitAlignment(unsigned NumBits) const { +void AsmPrinter::emitAlignment(unsigned NumBits, const GlobalValue *GV) const { + if (GV && GV->getAlignment()) + NumBits = Log2_32(GV->getAlignment()); if (NumBits == 0) return; // No need to emit alignment. if (AlignmentIsInBytes) NumBits = 1 << NumBits; O << AlignDirective << NumBits << "\n"; From lattner at cs.uiuc.edu Mon Nov 14 13:00:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 14 Nov 2005 13:00:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Message-ID: <200511141900.NAA24470@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.107 -> 1.108 --- Log message: Handle globals with explicit alignment requests --- Diffs of the changes: (+4 -4) PPCAsmPrinter.cpp | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.107 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.108 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.107 Mon Nov 14 12:52:46 2005 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Mon Nov 14 13:00:30 2005 @@ -74,7 +74,6 @@ else NS = NewSection; - if (CurSection != NS) { CurSection = NS; if (!CurSection.empty()) @@ -398,7 +397,7 @@ // Print out labels for the function. const Function *F = MF.getFunction(); SwitchSection(".text", F); - emitAlignment(4); + emitAlignment(4, F); if (!F->hasInternalLinkage()) O << "\t.globl\t" << CurrentFnName << "\n"; O << CurrentFnName << ":\n"; @@ -466,7 +465,8 @@ const TargetData &TD = TM.getTargetData(); // Print out module-level global variables here. - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) if (I->hasInitializer()) { // External global require no code O << '\n'; std::string name = Mang->getValueName(I); @@ -512,7 +512,7 @@ abort(); } - emitAlignment(Align); + emitAlignment(Align, I); O << name << ":\t\t\t\t; '" << I->getName() << "'\n"; emitGlobalConstant(C); } From alenhar2 at cs.uiuc.edu Mon Nov 14 13:32:17 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Mon, 14 Nov 2005 13:32:17 -0600 Subject: [llvm-commits] CVS: llvm/docs/CommandLine.html Message-ID: <200511141932.NAA24620@zion.cs.uiuc.edu> Changes in directory llvm/docs: CommandLine.html updated: 1.38 -> 1.39 --- Log message: this file moved --- Diffs of the changes: (+2 -2) CommandLine.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/docs/CommandLine.html diff -u llvm/docs/CommandLine.html:1.38 llvm/docs/CommandLine.html:1.39 --- llvm/docs/CommandLine.html:1.38 Fri Aug 26 04:25:54 2005 +++ llvm/docs/CommandLine.html Mon Nov 14 13:32:05 2005 @@ -195,7 +195,7 @@ program:

-  #include "Support/CommandLine.h"
+  #include "llvm/Support/CommandLine.h"
 

Additionally, you need to add this as the first line of your main @@ -1900,7 +1900,7 @@ Chris Lattner
LLVM Compiler Infrastructure
- Last modified: $Date: 2005/08/26 09:25:54 $ + Last modified: $Date: 2005/11/14 19:32:05 $ From lattner at cs.uiuc.edu Mon Nov 14 18:03:28 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 14 Nov 2005 18:03:28 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200511150003.SAA26893@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.24 -> 1.25 --- Log message: Remove extraneous parents around constants when using a constant expr cast. --- Diffs of the changes: (+0 -2) AsmPrinter.cpp | 2 -- 1 files changed, 2 deletions(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.24 llvm/lib/CodeGen/AsmPrinter.cpp:1.25 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.24 Mon Nov 14 13:00:06 2005 +++ llvm/lib/CodeGen/AsmPrinter.cpp Mon Nov 14 18:03:16 2005 @@ -118,9 +118,7 @@ || (((TD.getTypeSize(Ty) >= TD.getTypeSize(OpTy)) && OpTy->isLosslesslyConvertibleTo(Ty)))) && "FIXME: Don't yet support this kind of constant cast expr"); - O << "("; emitConstantValueOnly(Op); - O << ")"; break; } case Instruction::Add: From lattner at cs.uiuc.edu Mon Nov 14 18:40:36 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 14 Nov 2005 18:40:36 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86.h X86ISelPattern.cpp X86TargetMachine.cpp Message-ID: <200511150040.SAA27115@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp added (r1.1) X86ISelLowering.h added (r1.1) X86.h updated: 1.36 -> 1.37 X86ISelPattern.cpp updated: 1.184 -> 1.185 X86TargetMachine.cpp updated: 1.87 -> 1.88 --- Log message: Separate X86ISelLowering stuff out from the X86ISelPattern.cpp file. Patch contributed by Evan Cheng. --- Diffs of the changes: (+1061 -1007) X86.h | 12 X86ISelLowering.cpp | 916 ++++++++++++++++++++++++++++++++++++++++++++++ X86ISelLowering.h | 131 ++++++ X86ISelPattern.cpp | 1005 --------------------------------------------------- X86TargetMachine.cpp | 4 5 files changed, 1061 insertions(+), 1007 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -c /dev/null llvm/lib/Target/X86/X86ISelLowering.cpp:1.1 *** /dev/null Mon Nov 14 18:40:34 2005 --- llvm/lib/Target/X86/X86ISelLowering.cpp Mon Nov 14 18:40:24 2005 *************** *** 0 **** --- 1,916 ---- + //===-- X86ISelLowering.h - X86 DAG Lowering Interface ----------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Chris Lattner and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file defines the interfaces that X86 uses to lower LLVM code into a + // selection DAG. + // + //===----------------------------------------------------------------------===// + + #include "X86.h" + #include "X86ISelLowering.h" + #include "X86TargetMachine.h" + #include "llvm/CallingConv.h" + #include "llvm/Function.h" + #include "llvm/CodeGen/MachineFunction.h" + #include "llvm/CodeGen/MachineFrameInfo.h" + #include "llvm/CodeGen/SelectionDAG.h" + #include "llvm/CodeGen/SSARegMap.h" + #include "llvm/Target/TargetOptions.h" + using namespace llvm; + + // FIXME: temporary. + #include "llvm/Support/CommandLine.h" + static cl::opt EnableFastCC("enable-x86-fastcc", cl::Hidden, + cl::desc("Enable fastcc on X86")); + + X86TargetLowering::X86TargetLowering(TargetMachine &TM) + : TargetLowering(TM) { + + // Set up the TargetLowering object. + + // X86 is weird, it always uses i8 for shift amounts and setcc results. + setShiftAmountType(MVT::i8); + setSetCCResultType(MVT::i8); + setSetCCResultContents(ZeroOrOneSetCCResult); + setShiftAmountFlavor(Mask); // shl X, 32 == shl X, 0 + + // Set up the register classes. + // FIXME: Eliminate these two classes when legalize can handle promotions + // well. + addRegisterClass(MVT::i1, X86::R8RegisterClass); + addRegisterClass(MVT::i8, X86::R8RegisterClass); + addRegisterClass(MVT::i16, X86::R16RegisterClass); + addRegisterClass(MVT::i32, X86::R32RegisterClass); + + // Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this + // operation. + setOperationAction(ISD::UINT_TO_FP , MVT::i1 , Promote); + setOperationAction(ISD::UINT_TO_FP , MVT::i8 , Promote); + setOperationAction(ISD::UINT_TO_FP , MVT::i16 , Promote); + setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Promote); + + // Promote i1/i8 SINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have + // this operation. + setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote); + setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote); + + if (!X86ScalarSSE) { + // We can handle SINT_TO_FP and FP_TO_SINT from/TO i64 even though i64 + // isn't legal. + setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom); + setOperationAction(ISD::FP_TO_SINT , MVT::i64 , Custom); + setOperationAction(ISD::FP_TO_SINT , MVT::i32 , Custom); + setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Custom); + } + + // Handle FP_TO_UINT by promoting the destination to a larger signed + // conversion. + setOperationAction(ISD::FP_TO_UINT , MVT::i1 , Promote); + setOperationAction(ISD::FP_TO_UINT , MVT::i8 , Promote); + setOperationAction(ISD::FP_TO_UINT , MVT::i16 , Promote); + + if (!X86ScalarSSE) + setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Promote); + + // Promote i1/i8 FP_TO_SINT to larger FP_TO_SINTS's, as X86 doesn't have + // this operation. + setOperationAction(ISD::FP_TO_SINT , MVT::i1 , Promote); + setOperationAction(ISD::FP_TO_SINT , MVT::i8 , Promote); + setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Promote); + + setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand); + setOperationAction(ISD::BRTWOWAY_CC , MVT::Other, Expand); + setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); + setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand); + setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); + setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand); + setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand); + setOperationAction(ISD::FREM , MVT::f64 , Expand); + setOperationAction(ISD::CTPOP , MVT::i8 , Expand); + setOperationAction(ISD::CTTZ , MVT::i8 , Expand); + setOperationAction(ISD::CTLZ , MVT::i8 , Expand); + setOperationAction(ISD::CTPOP , MVT::i16 , Expand); + setOperationAction(ISD::CTTZ , MVT::i16 , Expand); + setOperationAction(ISD::CTLZ , MVT::i16 , Expand); + setOperationAction(ISD::CTPOP , MVT::i32 , Expand); + setOperationAction(ISD::CTTZ , MVT::i32 , Expand); + setOperationAction(ISD::CTLZ , MVT::i32 , Expand); + + setOperationAction(ISD::READIO , MVT::i1 , Expand); + setOperationAction(ISD::READIO , MVT::i8 , Expand); + setOperationAction(ISD::READIO , MVT::i16 , Expand); + setOperationAction(ISD::READIO , MVT::i32 , Expand); + setOperationAction(ISD::WRITEIO , MVT::i1 , Expand); + setOperationAction(ISD::WRITEIO , MVT::i8 , Expand); + setOperationAction(ISD::WRITEIO , MVT::i16 , Expand); + setOperationAction(ISD::WRITEIO , MVT::i32 , Expand); + + // These should be promoted to a larger select which is supported. + setOperationAction(ISD::SELECT , MVT::i1 , Promote); + setOperationAction(ISD::SELECT , MVT::i8 , Promote); + + if (X86ScalarSSE) { + // Set up the FP register classes. + addRegisterClass(MVT::f32, X86::V4F4RegisterClass); + addRegisterClass(MVT::f64, X86::V2F8RegisterClass); + + // SSE has no load+extend ops + setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); + setOperationAction(ISD::ZEXTLOAD, MVT::f32, Expand); + + // SSE has no i16 to fp conversion, only i32 + setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote); + setOperationAction(ISD::FP_TO_SINT, MVT::i16, Promote); + + // Expand FP_TO_UINT into a select. + // FIXME: We would like to use a Custom expander here eventually to do + // the optimal thing for SSE vs. the default expansion in the legalizer. + setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Expand); + + // We don't support sin/cos/sqrt/fmod + setOperationAction(ISD::FSIN , MVT::f64, Expand); + setOperationAction(ISD::FCOS , MVT::f64, Expand); + setOperationAction(ISD::FABS , MVT::f64, Expand); + setOperationAction(ISD::FNEG , MVT::f64, Expand); + setOperationAction(ISD::FREM , MVT::f64, Expand); + setOperationAction(ISD::FSIN , MVT::f32, Expand); + setOperationAction(ISD::FCOS , MVT::f32, Expand); + setOperationAction(ISD::FABS , MVT::f32, Expand); + setOperationAction(ISD::FNEG , MVT::f32, Expand); + setOperationAction(ISD::FREM , MVT::f32, Expand); + + addLegalFPImmediate(+0.0); // xorps / xorpd + } else { + // Set up the FP register classes. + addRegisterClass(MVT::f64, X86::RFPRegisterClass); + + if (!UnsafeFPMath) { + setOperationAction(ISD::FSIN , MVT::f64 , Expand); + setOperationAction(ISD::FCOS , MVT::f64 , Expand); + } + + addLegalFPImmediate(+0.0); // FLD0 + addLegalFPImmediate(+1.0); // FLD1 + addLegalFPImmediate(-0.0); // FLD0/FCHS + addLegalFPImmediate(-1.0); // FLD1/FCHS + } + computeRegisterProperties(); + + maxStoresPerMemSet = 8; // For %llvm.memset -> sequence of stores + maxStoresPerMemCpy = 8; // For %llvm.memcpy -> sequence of stores + maxStoresPerMemMove = 8; // For %llvm.memmove -> sequence of stores + allowUnalignedMemoryAccesses = true; // x86 supports it! + } + + std::vector + X86TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { + if (F.getCallingConv() == CallingConv::Fast && EnableFastCC) + return LowerFastCCArguments(F, DAG); + return LowerCCCArguments(F, DAG); + } + + std::pair + X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, + bool isVarArg, unsigned CallingConv, + bool isTailCall, + SDOperand Callee, ArgListTy &Args, + SelectionDAG &DAG) { + assert((!isVarArg || CallingConv == CallingConv::C) && + "Only C takes varargs!"); + if (CallingConv == CallingConv::Fast && EnableFastCC) + return LowerFastCCCallTo(Chain, RetTy, isTailCall, Callee, Args, DAG); + return LowerCCCCallTo(Chain, RetTy, isVarArg, isTailCall, Callee, Args, DAG); + } + + //===----------------------------------------------------------------------===// + // C Calling Convention implementation + //===----------------------------------------------------------------------===// + + std::vector + X86TargetLowering::LowerCCCArguments(Function &F, SelectionDAG &DAG) { + std::vector ArgValues; + + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + + // Add DAG nodes to load the arguments... On entry to a function on the X86, + // the stack frame looks like this: + // + // [ESP] -- return address + // [ESP + 4] -- first argument (leftmost lexically) + // [ESP + 8] -- second argument, if first argument is four bytes in size + // ... + // + unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot + for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { + MVT::ValueType ObjectVT = getValueType(I->getType()); + unsigned ArgIncrement = 4; + unsigned ObjSize; + switch (ObjectVT) { + default: assert(0 && "Unhandled argument type!"); + case MVT::i1: + case MVT::i8: ObjSize = 1; break; + case MVT::i16: ObjSize = 2; break; + case MVT::i32: ObjSize = 4; break; + case MVT::i64: ObjSize = ArgIncrement = 8; break; + case MVT::f32: ObjSize = 4; break; + case MVT::f64: ObjSize = ArgIncrement = 8; break; + } + // Create the frame index object for this incoming parameter... + int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); + + // Create the SelectionDAG nodes corresponding to a load from this parameter + SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); + + // Don't codegen dead arguments. FIXME: remove this check when we can nuke + // dead loads. + SDOperand ArgValue; + if (!I->use_empty()) + ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN, + DAG.getSrcValue(NULL)); + else { + if (MVT::isInteger(ObjectVT)) + ArgValue = DAG.getConstant(0, ObjectVT); + else + ArgValue = DAG.getConstantFP(0, ObjectVT); + } + ArgValues.push_back(ArgValue); + + ArgOffset += ArgIncrement; // Move on to the next argument... + } + + // If the function takes variable number of arguments, make a frame index for + // the start of the first vararg value... for expansion of llvm.va_start. + if (F.isVarArg()) + VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset); + ReturnAddrIndex = 0; // No return address slot generated yet. + BytesToPopOnReturn = 0; // Callee pops nothing. + BytesCallerReserves = ArgOffset; + + // Finally, inform the code generator which regs we return values in. + switch (getValueType(F.getReturnType())) { + default: assert(0 && "Unknown type!"); + case MVT::isVoid: break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + MF.addLiveOut(X86::EAX); + break; + case MVT::i64: + MF.addLiveOut(X86::EAX); + MF.addLiveOut(X86::EDX); + break; + case MVT::f32: + case MVT::f64: + MF.addLiveOut(X86::ST0); + break; + } + return ArgValues; + } + + std::pair + X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy, + bool isVarArg, bool isTailCall, + SDOperand Callee, ArgListTy &Args, + SelectionDAG &DAG) { + // Count how many bytes are to be pushed on the stack. + unsigned NumBytes = 0; + + if (Args.empty()) { + // Save zero bytes. + Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, + DAG.getConstant(0, getPointerTy())); + } else { + for (unsigned i = 0, e = Args.size(); i != e; ++i) + switch (getValueType(Args[i].second)) { + default: assert(0 && "Unknown value type!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::f32: + NumBytes += 4; + break; + case MVT::i64: + case MVT::f64: + NumBytes += 8; + break; + } + + Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, + DAG.getConstant(NumBytes, getPointerTy())); + + // Arguments go on the stack in reverse order, as specified by the ABI. + unsigned ArgOffset = 0; + SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(), + X86::ESP, MVT::i32); + std::vector Stores; + + for (unsigned i = 0, e = Args.size(); i != e; ++i) { + SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); + + switch (getValueType(Args[i].second)) { + default: assert(0 && "Unexpected ValueType for argument!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + // Promote the integer to 32 bits. If the input type is signed use a + // sign extend, otherwise use a zero extend. + if (Args[i].second->isSigned()) + Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first); + else + Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first); + + // FALL THROUGH + case MVT::i32: + case MVT::f32: + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff, + DAG.getSrcValue(NULL))); + ArgOffset += 4; + break; + case MVT::i64: + case MVT::f64: + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff, + DAG.getSrcValue(NULL))); + ArgOffset += 8; + break; + } + } + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores); + } + + std::vector RetVals; + MVT::ValueType RetTyVT = getValueType(RetTy); + RetVals.push_back(MVT::Other); + + // The result values produced have to be legal. Promote the result. + switch (RetTyVT) { + case MVT::isVoid: break; + default: + RetVals.push_back(RetTyVT); + break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + RetVals.push_back(MVT::i32); + break; + case MVT::f32: + if (X86ScalarSSE) + RetVals.push_back(MVT::f32); + else + RetVals.push_back(MVT::f64); + break; + case MVT::i64: + RetVals.push_back(MVT::i32); + RetVals.push_back(MVT::i32); + break; + } + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(Callee); + Ops.push_back(DAG.getConstant(NumBytes, getPointerTy())); + Ops.push_back(DAG.getConstant(0, getPointerTy())); + SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, + RetVals, Ops); + Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall); + + SDOperand ResultVal; + switch (RetTyVT) { + case MVT::isVoid: break; + default: + ResultVal = TheCall.getValue(1); + break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1)); + break; + case MVT::f32: + // FIXME: we would really like to remember that this FP_ROUND operation is + // okay to eliminate if we allow excess FP precision. + ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1)); + break; + case MVT::i64: + ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1), + TheCall.getValue(2)); + break; + } + + return std::make_pair(ResultVal, Chain); + } + + SDOperand + X86TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG) { + // vastart just stores the address of the VarArgsFrameIndex slot. + SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); + return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, + DAG.getSrcValue(VAListV)); + } + + + std::pair + X86TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, + Value *VAListV, const Type *ArgTy, + SelectionDAG &DAG) { + MVT::ValueType ArgVT = getValueType(ArgTy); + SDOperand Val = DAG.getLoad(MVT::i32, Chain, + VAListP, DAG.getSrcValue(VAListV)); + SDOperand Result = DAG.getLoad(ArgVT, Chain, Val, + DAG.getSrcValue(NULL)); + unsigned Amt; + if (ArgVT == MVT::i32) + Amt = 4; + else { + assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && + "Other types should have been promoted for varargs!"); + Amt = 8; + } + Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val, + DAG.getConstant(Amt, Val.getValueType())); + Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, + Val, VAListP, DAG.getSrcValue(VAListV)); + return std::make_pair(Result, Chain); + } + + //===----------------------------------------------------------------------===// + // Fast Calling Convention implementation + //===----------------------------------------------------------------------===// + // + // The X86 'fast' calling convention passes up to two integer arguments in + // registers (an appropriate portion of EAX/EDX), passes arguments in C order, + // and requires that the callee pop its arguments off the stack (allowing proper + // tail calls), and has the same return value conventions as C calling convs. + // + // This calling convention always arranges for the callee pop value to be 8n+4 + // bytes, which is needed for tail recursion elimination and stack alignment + // reasons. + // + // Note that this can be enhanced in the future to pass fp vals in registers + // (when we have a global fp allocator) and do other tricks. + // + + /// AddLiveIn - This helper function adds the specified physical register to the + /// MachineFunction as a live in value. It also creates a corresponding virtual + /// register for it. + static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg, + TargetRegisterClass *RC) { + assert(RC->contains(PReg) && "Not the correct regclass!"); + unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC); + MF.addLiveIn(PReg, VReg); + return VReg; + } + + + std::vector + X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) { + std::vector ArgValues; + + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + + // Add DAG nodes to load the arguments... On entry to a function the stack + // frame looks like this: + // + // [ESP] -- return address + // [ESP + 4] -- first nonreg argument (leftmost lexically) + // [ESP + 8] -- second nonreg argument, if first argument is 4 bytes in size + // ... + unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot + + // Keep track of the number of integer regs passed so far. This can be either + // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both + // used). + unsigned NumIntRegs = 0; + + for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { + MVT::ValueType ObjectVT = getValueType(I->getType()); + unsigned ArgIncrement = 4; + unsigned ObjSize = 0; + SDOperand ArgValue; + + switch (ObjectVT) { + default: assert(0 && "Unhandled argument type!"); + case MVT::i1: + case MVT::i8: + if (NumIntRegs < 2) { + if (!I->use_empty()) { + unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DL : X86::AL, + X86::R8RegisterClass); + ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i8); + DAG.setRoot(ArgValue.getValue(1)); + } + ++NumIntRegs; + break; + } + + ObjSize = 1; + break; + case MVT::i16: + if (NumIntRegs < 2) { + if (!I->use_empty()) { + unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DX : X86::AX, + X86::R16RegisterClass); + ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i16); + DAG.setRoot(ArgValue.getValue(1)); + } + ++NumIntRegs; + break; + } + ObjSize = 2; + break; + case MVT::i32: + if (NumIntRegs < 2) { + if (!I->use_empty()) { + unsigned VReg = AddLiveIn(MF,NumIntRegs ? X86::EDX : X86::EAX, + X86::R32RegisterClass); + ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32); + DAG.setRoot(ArgValue.getValue(1)); + } + ++NumIntRegs; + break; + } + ObjSize = 4; + break; + case MVT::i64: + if (NumIntRegs == 0) { + if (!I->use_empty()) { + unsigned BotReg = AddLiveIn(MF, X86::EAX, X86::R32RegisterClass); + unsigned TopReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass); + + SDOperand Low = DAG.getCopyFromReg(DAG.getRoot(), BotReg, MVT::i32); + SDOperand Hi = DAG.getCopyFromReg(Low.getValue(1), TopReg, MVT::i32); + DAG.setRoot(Hi.getValue(1)); + + ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Low, Hi); + } + NumIntRegs = 2; + break; + } else if (NumIntRegs == 1) { + if (!I->use_empty()) { + unsigned BotReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass); + SDOperand Low = DAG.getCopyFromReg(DAG.getRoot(), BotReg, MVT::i32); + DAG.setRoot(Low.getValue(1)); + + // Load the high part from memory. + // Create the frame index object for this incoming parameter... + int FI = MFI->CreateFixedObject(4, ArgOffset); + SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); + SDOperand Hi = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN, + DAG.getSrcValue(NULL)); + ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Low, Hi); + } + ArgOffset += 4; + NumIntRegs = 2; + break; + } + ObjSize = ArgIncrement = 8; + break; + case MVT::f32: ObjSize = 4; break; + case MVT::f64: ObjSize = ArgIncrement = 8; break; + } + + // Don't codegen dead arguments. FIXME: remove this check when we can nuke + // dead loads. + if (ObjSize && !I->use_empty()) { + // Create the frame index object for this incoming parameter... + int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); + + // Create the SelectionDAG nodes corresponding to a load from this + // parameter. + SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); + + ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN, + DAG.getSrcValue(NULL)); + } else if (ArgValue.Val == 0) { + if (MVT::isInteger(ObjectVT)) + ArgValue = DAG.getConstant(0, ObjectVT); + else + ArgValue = DAG.getConstantFP(0, ObjectVT); + } + ArgValues.push_back(ArgValue); + + if (ObjSize) + ArgOffset += ArgIncrement; // Move on to the next argument. + } + + // Make sure the instruction takes 8n+4 bytes to make sure the start of the + // arguments and the arguments after the retaddr has been pushed are aligned. + if ((ArgOffset & 7) == 0) + ArgOffset += 4; + + VarArgsFrameIndex = 0xAAAAAAA; // fastcc functions can't have varargs. + ReturnAddrIndex = 0; // No return address slot generated yet. + BytesToPopOnReturn = ArgOffset; // Callee pops all stack arguments. + BytesCallerReserves = 0; + + // Finally, inform the code generator which regs we return values in. + switch (getValueType(F.getReturnType())) { + default: assert(0 && "Unknown type!"); + case MVT::isVoid: break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + MF.addLiveOut(X86::EAX); + break; + case MVT::i64: + MF.addLiveOut(X86::EAX); + MF.addLiveOut(X86::EDX); + break; + case MVT::f32: + case MVT::f64: + MF.addLiveOut(X86::ST0); + break; + } + return ArgValues; + } + + std::pair + X86TargetLowering::LowerFastCCCallTo(SDOperand Chain, const Type *RetTy, + bool isTailCall, SDOperand Callee, + ArgListTy &Args, SelectionDAG &DAG) { + // Count how many bytes are to be pushed on the stack. + unsigned NumBytes = 0; + + // Keep track of the number of integer regs passed so far. This can be either + // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both + // used). + unsigned NumIntRegs = 0; + + for (unsigned i = 0, e = Args.size(); i != e; ++i) + switch (getValueType(Args[i].second)) { + default: assert(0 && "Unknown value type!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + if (NumIntRegs < 2) { + ++NumIntRegs; + break; + } + // fall through + case MVT::f32: + NumBytes += 4; + break; + case MVT::i64: + if (NumIntRegs == 0) { + NumIntRegs = 2; + break; + } else if (NumIntRegs == 1) { + NumIntRegs = 2; + NumBytes += 4; + break; + } + + // fall through + case MVT::f64: + NumBytes += 8; + break; + } + + // Make sure the instruction takes 8n+4 bytes to make sure the start of the + // arguments and the arguments after the retaddr has been pushed are aligned. + if ((NumBytes & 7) == 0) + NumBytes += 4; + + Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, + DAG.getConstant(NumBytes, getPointerTy())); + + // Arguments go on the stack in reverse order, as specified by the ABI. + unsigned ArgOffset = 0; + SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(), + X86::ESP, MVT::i32); + NumIntRegs = 0; + std::vector Stores; + std::vector RegValuesToPass; + for (unsigned i = 0, e = Args.size(); i != e; ++i) { + switch (getValueType(Args[i].second)) { + default: assert(0 && "Unexpected ValueType for argument!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + if (NumIntRegs < 2) { + RegValuesToPass.push_back(Args[i].first); + ++NumIntRegs; + break; + } + // Fall through + case MVT::f32: { + SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff, + DAG.getSrcValue(NULL))); + ArgOffset += 4; + break; + } + case MVT::i64: + if (NumIntRegs < 2) { // Can pass part of it in regs? + SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, + Args[i].first, DAG.getConstant(1, MVT::i32)); + SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, + Args[i].first, DAG.getConstant(0, MVT::i32)); + RegValuesToPass.push_back(Lo); + ++NumIntRegs; + if (NumIntRegs < 2) { // Pass both parts in regs? + RegValuesToPass.push_back(Hi); + ++NumIntRegs; + } else { + // Pass the high part in memory. + SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Hi, PtrOff, DAG.getSrcValue(NULL))); + ArgOffset += 4; + } + break; + } + // Fall through + case MVT::f64: + SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff, + DAG.getSrcValue(NULL))); + ArgOffset += 8; + break; + } + } + if (!Stores.empty()) + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores); + + // Make sure the instruction takes 8n+4 bytes to make sure the start of the + // arguments and the arguments after the retaddr has been pushed are aligned. + if ((ArgOffset & 7) == 0) + ArgOffset += 4; + + std::vector RetVals; + MVT::ValueType RetTyVT = getValueType(RetTy); + + RetVals.push_back(MVT::Other); + + // The result values produced have to be legal. Promote the result. + switch (RetTyVT) { + case MVT::isVoid: break; + default: + RetVals.push_back(RetTyVT); + break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + RetVals.push_back(MVT::i32); + break; + case MVT::f32: + if (X86ScalarSSE) + RetVals.push_back(MVT::f32); + else + RetVals.push_back(MVT::f64); + break; + case MVT::i64: + RetVals.push_back(MVT::i32); + RetVals.push_back(MVT::i32); + break; + } + + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(Callee); + Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy())); + // Callee pops all arg values on the stack. + Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy())); + + // Pass register arguments as needed. + Ops.insert(Ops.end(), RegValuesToPass.begin(), RegValuesToPass.end()); + + SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, + RetVals, Ops); + Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall); + + SDOperand ResultVal; + switch (RetTyVT) { + case MVT::isVoid: break; + default: + ResultVal = TheCall.getValue(1); + break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1)); + break; + case MVT::f32: + // FIXME: we would really like to remember that this FP_ROUND operation is + // okay to eliminate if we allow excess FP precision. + ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1)); + break; + case MVT::i64: + ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1), + TheCall.getValue(2)); + break; + } + + return std::make_pair(ResultVal, Chain); + } + + SDOperand X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) { + if (ReturnAddrIndex == 0) { + // Set up a frame object for the return address. + MachineFunction &MF = DAG.getMachineFunction(); + ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(4, -4); + } + + return DAG.getFrameIndex(ReturnAddrIndex, MVT::i32); + } + + + + std::pair X86TargetLowering:: + LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, + SelectionDAG &DAG) { + SDOperand Result; + if (Depth) // Depths > 0 not supported yet! + Result = DAG.getConstant(0, getPointerTy()); + else { + SDOperand RetAddrFI = getReturnAddressFrameIndex(DAG); + if (!isFrameAddress) + // Just load the return address + Result = DAG.getLoad(MVT::i32, DAG.getEntryNode(), RetAddrFI, + DAG.getSrcValue(NULL)); + else + Result = DAG.getNode(ISD::SUB, MVT::i32, RetAddrFI, + DAG.getConstant(4, MVT::i32)); + } + return std::make_pair(Result, Chain); + } + + //===----------------------------------------------------------------------===// + // X86 Custom Lowering Hooks + //===----------------------------------------------------------------------===// + + /// LowerOperation - Provide custom lowering hooks for some operations. + /// + SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { + switch (Op.getOpcode()) { + default: assert(0 && "Should not custom lower this!"); + case ISD::SINT_TO_FP: { + assert(Op.getValueType() == MVT::f64 && + Op.getOperand(0).getValueType() == MVT::i64 && + "Unknown SINT_TO_FP to lower!"); + // We lower sint64->FP into a store to a temporary stack slot, followed by a + // FILD64m node. + MachineFunction &MF = DAG.getMachineFunction(); + int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8); + SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); + SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), + Op.getOperand(0), StackSlot, DAG.getSrcValue(NULL)); + std::vector RTs; + RTs.push_back(MVT::f64); + RTs.push_back(MVT::Other); + std::vector Ops; + Ops.push_back(Store); + Ops.push_back(StackSlot); + return DAG.getNode(X86ISD::FILD64m, RTs, Ops); + } + case ISD::FP_TO_SINT: { + assert(Op.getValueType() <= MVT::i64 && Op.getValueType() >= MVT::i16 && + Op.getOperand(0).getValueType() == MVT::f64 && + "Unknown FP_TO_SINT to lower!"); + // We lower FP->sint64 into FISTP64, followed by a load, all to a temporary + // stack slot. + MachineFunction &MF = DAG.getMachineFunction(); + unsigned MemSize = MVT::getSizeInBits(Op.getValueType())/8; + int SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize); + SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); + + unsigned Opc; + switch (Op.getValueType()) { + default: assert(0 && "Invalid FP_TO_SINT to lower!"); + case MVT::i16: Opc = X86ISD::FP_TO_INT16_IN_MEM; break; + case MVT::i32: Opc = X86ISD::FP_TO_INT32_IN_MEM; break; + case MVT::i64: Opc = X86ISD::FP_TO_INT64_IN_MEM; break; + } + + // Build the FP_TO_INT*_IN_MEM + std::vector Ops; + Ops.push_back(DAG.getEntryNode()); + Ops.push_back(Op.getOperand(0)); + Ops.push_back(StackSlot); + SDOperand FIST = DAG.getNode(Opc, MVT::Other, Ops); + + // Load the result. + return DAG.getLoad(Op.getValueType(), FIST, StackSlot, + DAG.getSrcValue(NULL)); + } + } + } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -c /dev/null llvm/lib/Target/X86/X86ISelLowering.h:1.1 *** /dev/null Mon Nov 14 18:40:36 2005 --- llvm/lib/Target/X86/X86ISelLowering.h Mon Nov 14 18:40:24 2005 *************** *** 0 **** --- 1,131 ---- + //===-- X86ISelLowering.h - X86 DAG Lowering Interface ----------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Chris Lattner and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file defines the interfaces that X86 uses to lower LLVM code into a + // selection DAG. + // + //===----------------------------------------------------------------------===// + + #ifndef X86ISELLOWERING_H + #define X86ISELLOWERING_H + + #include "llvm/Target/TargetLowering.h" + #include "llvm/CodeGen/SelectionDAG.h" + + namespace llvm { + // X86 Specific DAG Nodes + namespace X86ISD { + enum NodeType { + // Start the numbering where the builtin ops leave off. + FIRST_NUMBER = ISD::BUILTIN_OP_END, + + /// FILD64m - This instruction implements SINT_TO_FP with a + /// 64-bit source in memory and a FP reg result. This corresponds to + /// the X86::FILD64m instruction. It has two inputs (token chain and + /// address) and two outputs (FP value and token chain). + FILD64m, + + /// FP_TO_INT*_IN_MEM - This instruction implements FP_TO_SINT with the + /// integer destination in memory and a FP reg source. This corresponds + /// to the X86::FIST*m instructions and the rounding mode change stuff. It + /// has two inputs (token chain and address) and two outputs (FP value and + /// token chain). + FP_TO_INT16_IN_MEM, + FP_TO_INT32_IN_MEM, + FP_TO_INT64_IN_MEM, + + /// CALL/TAILCALL - These operations represent an abstract X86 call + /// instruction, which includes a bunch of information. In particular the + /// operands of these node are: + /// + /// #0 - The incoming token chain + /// #1 - The callee + /// #2 - The number of arg bytes the caller pushes on the stack. + /// #3 - The number of arg bytes the callee pops off the stack. + /// #4 - The value to pass in AL/AX/EAX (optional) + /// #5 - The value to pass in DL/DX/EDX (optional) + /// + /// The result values of these nodes are: + /// + /// #0 - The outgoing token chain + /// #1 - The first register result value (optional) + /// #2 - The second register result value (optional) + /// + /// The CALL vs TAILCALL distinction boils down to whether the callee is + /// known not to modify the caller's stack frame, as is standard with + /// LLVM. + CALL, + TAILCALL, + }; + } + + //===----------------------------------------------------------------------===// + // X86TargetLowering - X86 Implementation of the TargetLowering interface + class X86TargetLowering : public TargetLowering { + int VarArgsFrameIndex; // FrameIndex for start of varargs area. + int ReturnAddrIndex; // FrameIndex for return slot. + int BytesToPopOnReturn; // Number of arg bytes ret should pop. + int BytesCallerReserves; // Number of arg bytes caller makes. + public: + X86TargetLowering(TargetMachine &TM); + + // Return the number of bytes that a function should pop when it returns (in + // addition to the space used by the return address). + // + unsigned getBytesToPopOnReturn() const { return BytesToPopOnReturn; } + + // Return the number of bytes that the caller reserves for arguments passed + // to this function. + unsigned getBytesCallerReserves() const { return BytesCallerReserves; } + + /// LowerOperation - Provide custom lowering hooks for some operations. + /// + virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); + + /// LowerArguments - This hook must be implemented to indicate how we should + /// lower the arguments for the specified function, into the specified DAG. + virtual std::vector + LowerArguments(Function &F, SelectionDAG &DAG); + + /// LowerCallTo - This hook lowers an abstract call to a function into an + /// actual call. + virtual std::pair + LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, unsigned CC, + bool isTailCall, SDOperand Callee, ArgListTy &Args, + SelectionDAG &DAG); + + virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG); + virtual std::pair + LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG); + + virtual std::pair + LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, + SelectionDAG &DAG); + + SDOperand getReturnAddressFrameIndex(SelectionDAG &DAG); + + private: + // C Calling Convention implementation. + std::vector LowerCCCArguments(Function &F, SelectionDAG &DAG); + std::pair + LowerCCCCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, + bool isTailCall, + SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); + + // Fast Calling Convention implementation. + std::vector LowerFastCCArguments(Function &F, SelectionDAG &DAG); + std::pair + LowerFastCCCallTo(SDOperand Chain, const Type *RetTy, bool isTailCall, + SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); + }; + } + + #endif // X86ISELLOWERING_H Index: llvm/lib/Target/X86/X86.h diff -u llvm/lib/Target/X86/X86.h:1.36 llvm/lib/Target/X86/X86.h:1.37 --- llvm/lib/Target/X86/X86.h:1.36 Thu Aug 18 18:53:15 2005 +++ llvm/lib/Target/X86/X86.h Mon Nov 14 18:40:24 2005 @@ -32,10 +32,16 @@ extern X86VectorEnum X86Vector; extern bool X86ScalarSSE; -/// createX86PatternInstructionSelector - This pass converts an LLVM function -/// into a machine code representation in a more aggressive way. +/// createX86ISelPattern - This pass converts an LLVM function into a +/// machine code representation using pattern matching and a machine +/// description file. /// -FunctionPass *createX86PatternInstructionSelector(TargetMachine &TM); +FunctionPass *createX86ISelPattern(TargetMachine &TM); + +/// createX86ISelDag - This pass converts a legalized DAG into a +/// X86-specific DAG, ready for instruction scheduling. +/// +FunctionPass *createX86ISelDag(TargetMachine &TM); /// createX86SSAPeepholeOptimizerPass - Create a pass to perform SSA-based X86 /// specific peephole optimizations. Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.184 llvm/lib/Target/X86/X86ISelPattern.cpp:1.185 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.184 Thu Oct 20 19:02:42 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Mon Nov 14 18:40:24 2005 @@ -15,6 +15,7 @@ #include "X86InstrBuilder.h" #include "X86RegisterInfo.h" #include "X86Subtarget.h" +#include "X86ISelLowering.h" #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" @@ -36,1006 +37,6 @@ #include using namespace llvm; -// FIXME: temporary. -#include "llvm/Support/CommandLine.h" -static cl::opt EnableFastCC("enable-x86-fastcc", cl::Hidden, - cl::desc("Enable fastcc on X86")); - -namespace { - // X86 Specific DAG Nodes - namespace X86ISD { - enum NodeType { - // Start the numbering where the builtin ops leave off. - FIRST_NUMBER = ISD::BUILTIN_OP_END, - - /// FILD64m - This instruction implements SINT_TO_FP with a - /// 64-bit source in memory and a FP reg result. This corresponds to - /// the X86::FILD64m instruction. It has two inputs (token chain and - /// address) and two outputs (FP value and token chain). - FILD64m, - - /// FP_TO_INT*_IN_MEM - This instruction implements FP_TO_SINT with the - /// integer destination in memory and a FP reg source. This corresponds - /// to the X86::FIST*m instructions and the rounding mode change stuff. It - /// has two inputs (token chain and address) and two outputs (FP value and - /// token chain). - FP_TO_INT16_IN_MEM, - FP_TO_INT32_IN_MEM, - FP_TO_INT64_IN_MEM, - - /// CALL/TAILCALL - These operations represent an abstract X86 call - /// instruction, which includes a bunch of information. In particular the - /// operands of these node are: - /// - /// #0 - The incoming token chain - /// #1 - The callee - /// #2 - The number of arg bytes the caller pushes on the stack. - /// #3 - The number of arg bytes the callee pops off the stack. - /// #4 - The value to pass in AL/AX/EAX (optional) - /// #5 - The value to pass in DL/DX/EDX (optional) - /// - /// The result values of these nodes are: - /// - /// #0 - The outgoing token chain - /// #1 - The first register result value (optional) - /// #2 - The second register result value (optional) - /// - /// The CALL vs TAILCALL distinction boils down to whether the callee is - /// known not to modify the caller's stack frame, as is standard with - /// LLVM. - CALL, - TAILCALL, - }; - } -} - -//===----------------------------------------------------------------------===// -// X86TargetLowering - X86 Implementation of the TargetLowering interface -namespace { - class X86TargetLowering : public TargetLowering { - int VarArgsFrameIndex; // FrameIndex for start of varargs area. - int ReturnAddrIndex; // FrameIndex for return slot. - int BytesToPopOnReturn; // Number of arg bytes ret should pop. - int BytesCallerReserves; // Number of arg bytes caller makes. - public: - X86TargetLowering(TargetMachine &TM) : TargetLowering(TM) { - // Set up the TargetLowering object. - - // X86 is weird, it always uses i8 for shift amounts and setcc results. - setShiftAmountType(MVT::i8); - setSetCCResultType(MVT::i8); - setSetCCResultContents(ZeroOrOneSetCCResult); - setShiftAmountFlavor(Mask); // shl X, 32 == shl X, 0 - - // Set up the register classes. - // FIXME: Eliminate these two classes when legalize can handle promotions - // well. - addRegisterClass(MVT::i1, X86::R8RegisterClass); - addRegisterClass(MVT::i8, X86::R8RegisterClass); - addRegisterClass(MVT::i16, X86::R16RegisterClass); - addRegisterClass(MVT::i32, X86::R32RegisterClass); - - // Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this - // operation. - setOperationAction(ISD::UINT_TO_FP , MVT::i1 , Promote); - setOperationAction(ISD::UINT_TO_FP , MVT::i8 , Promote); - setOperationAction(ISD::UINT_TO_FP , MVT::i16 , Promote); - setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Promote); - - // Promote i1/i8 SINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have - // this operation. - setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote); - setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote); - - if (!X86ScalarSSE) { - // We can handle SINT_TO_FP and FP_TO_SINT from/TO i64 even though i64 - // isn't legal. - setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom); - setOperationAction(ISD::FP_TO_SINT , MVT::i64 , Custom); - setOperationAction(ISD::FP_TO_SINT , MVT::i32 , Custom); - setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Custom); - } - - // Handle FP_TO_UINT by promoting the destination to a larger signed - // conversion. - setOperationAction(ISD::FP_TO_UINT , MVT::i1 , Promote); - setOperationAction(ISD::FP_TO_UINT , MVT::i8 , Promote); - setOperationAction(ISD::FP_TO_UINT , MVT::i16 , Promote); - - if (!X86ScalarSSE) - setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Promote); - - // Promote i1/i8 FP_TO_SINT to larger FP_TO_SINTS's, as X86 doesn't have - // this operation. - setOperationAction(ISD::FP_TO_SINT , MVT::i1 , Promote); - setOperationAction(ISD::FP_TO_SINT , MVT::i8 , Promote); - setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Promote); - - setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand); - setOperationAction(ISD::BRTWOWAY_CC , MVT::Other, Expand); - setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); - setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand); - setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); - setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand); - setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand); - setOperationAction(ISD::FREM , MVT::f64 , Expand); - setOperationAction(ISD::CTPOP , MVT::i8 , Expand); - setOperationAction(ISD::CTTZ , MVT::i8 , Expand); - setOperationAction(ISD::CTLZ , MVT::i8 , Expand); - setOperationAction(ISD::CTPOP , MVT::i16 , Expand); - setOperationAction(ISD::CTTZ , MVT::i16 , Expand); - setOperationAction(ISD::CTLZ , MVT::i16 , Expand); - setOperationAction(ISD::CTPOP , MVT::i32 , Expand); - setOperationAction(ISD::CTTZ , MVT::i32 , Expand); - setOperationAction(ISD::CTLZ , MVT::i32 , Expand); - - setOperationAction(ISD::READIO , MVT::i1 , Expand); - setOperationAction(ISD::READIO , MVT::i8 , Expand); - setOperationAction(ISD::READIO , MVT::i16 , Expand); - setOperationAction(ISD::READIO , MVT::i32 , Expand); - setOperationAction(ISD::WRITEIO , MVT::i1 , Expand); - setOperationAction(ISD::WRITEIO , MVT::i8 , Expand); - setOperationAction(ISD::WRITEIO , MVT::i16 , Expand); - setOperationAction(ISD::WRITEIO , MVT::i32 , Expand); - - // These should be promoted to a larger select which is supported. - setOperationAction(ISD::SELECT , MVT::i1 , Promote); - setOperationAction(ISD::SELECT , MVT::i8 , Promote); - - if (X86ScalarSSE) { - // Set up the FP register classes. - addRegisterClass(MVT::f32, X86::V4F4RegisterClass); - addRegisterClass(MVT::f64, X86::V2F8RegisterClass); - - // SSE has no load+extend ops - setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); - setOperationAction(ISD::ZEXTLOAD, MVT::f32, Expand); - - // SSE has no i16 to fp conversion, only i32 - setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote); - setOperationAction(ISD::FP_TO_SINT, MVT::i16, Promote); - - // Expand FP_TO_UINT into a select. - // FIXME: We would like to use a Custom expander here eventually to do - // the optimal thing for SSE vs. the default expansion in the legalizer. - setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Expand); - - // We don't support sin/cos/sqrt/fmod - setOperationAction(ISD::FSIN , MVT::f64, Expand); - setOperationAction(ISD::FCOS , MVT::f64, Expand); - setOperationAction(ISD::FABS , MVT::f64, Expand); - setOperationAction(ISD::FNEG , MVT::f64, Expand); - setOperationAction(ISD::FREM , MVT::f64, Expand); - setOperationAction(ISD::FSIN , MVT::f32, Expand); - setOperationAction(ISD::FCOS , MVT::f32, Expand); - setOperationAction(ISD::FABS , MVT::f32, Expand); - setOperationAction(ISD::FNEG , MVT::f32, Expand); - setOperationAction(ISD::FREM , MVT::f32, Expand); - - addLegalFPImmediate(+0.0); // xorps / xorpd - } else { - // Set up the FP register classes. - addRegisterClass(MVT::f64, X86::RFPRegisterClass); - - if (!UnsafeFPMath) { - setOperationAction(ISD::FSIN , MVT::f64 , Expand); - setOperationAction(ISD::FCOS , MVT::f64 , Expand); - } - - addLegalFPImmediate(+0.0); // FLD0 - addLegalFPImmediate(+1.0); // FLD1 - addLegalFPImmediate(-0.0); // FLD0/FCHS - addLegalFPImmediate(-1.0); // FLD1/FCHS - } - computeRegisterProperties(); - - maxStoresPerMemSet = 8; // For %llvm.memset -> sequence of stores - maxStoresPerMemCpy = 8; // For %llvm.memcpy -> sequence of stores - maxStoresPerMemMove = 8; // For %llvm.memmove -> sequence of stores - allowUnalignedMemoryAccesses = true; // x86 supports it! - } - - // Return the number of bytes that a function should pop when it returns (in - // addition to the space used by the return address). - // - unsigned getBytesToPopOnReturn() const { return BytesToPopOnReturn; } - - // Return the number of bytes that the caller reserves for arguments passed - // to this function. - unsigned getBytesCallerReserves() const { return BytesCallerReserves; } - - /// LowerOperation - Provide custom lowering hooks for some operations. - /// - virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); - - /// LowerArguments - This hook must be implemented to indicate how we should - /// lower the arguments for the specified function, into the specified DAG. - virtual std::vector - LowerArguments(Function &F, SelectionDAG &DAG); - - /// LowerCallTo - This hook lowers an abstract call to a function into an - /// actual call. - virtual std::pair - LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, unsigned CC, - bool isTailCall, SDOperand Callee, ArgListTy &Args, - SelectionDAG &DAG); - - virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG); - virtual std::pair - LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG); - - virtual std::pair - LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, - SelectionDAG &DAG); - - SDOperand getReturnAddressFrameIndex(SelectionDAG &DAG); - - private: - // C Calling Convention implementation. - std::vector LowerCCCArguments(Function &F, SelectionDAG &DAG); - std::pair - LowerCCCCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, - bool isTailCall, - SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); - - // Fast Calling Convention implementation. - std::vector LowerFastCCArguments(Function &F, SelectionDAG &DAG); - std::pair - LowerFastCCCallTo(SDOperand Chain, const Type *RetTy, bool isTailCall, - SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); - }; -} - -std::vector -X86TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { - if (F.getCallingConv() == CallingConv::Fast && EnableFastCC) - return LowerFastCCArguments(F, DAG); - return LowerCCCArguments(F, DAG); -} - -std::pair -X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, - bool isVarArg, unsigned CallingConv, - bool isTailCall, - SDOperand Callee, ArgListTy &Args, - SelectionDAG &DAG) { - assert((!isVarArg || CallingConv == CallingConv::C) && - "Only C takes varargs!"); - if (CallingConv == CallingConv::Fast && EnableFastCC) - return LowerFastCCCallTo(Chain, RetTy, isTailCall, Callee, Args, DAG); - return LowerCCCCallTo(Chain, RetTy, isVarArg, isTailCall, Callee, Args, DAG); -} - -//===----------------------------------------------------------------------===// -// C Calling Convention implementation -//===----------------------------------------------------------------------===// - -std::vector -X86TargetLowering::LowerCCCArguments(Function &F, SelectionDAG &DAG) { - std::vector ArgValues; - - MachineFunction &MF = DAG.getMachineFunction(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - - // Add DAG nodes to load the arguments... On entry to a function on the X86, - // the stack frame looks like this: - // - // [ESP] -- return address - // [ESP + 4] -- first argument (leftmost lexically) - // [ESP + 8] -- second argument, if first argument is four bytes in size - // ... - // - unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot - for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { - MVT::ValueType ObjectVT = getValueType(I->getType()); - unsigned ArgIncrement = 4; - unsigned ObjSize; - switch (ObjectVT) { - default: assert(0 && "Unhandled argument type!"); - case MVT::i1: - case MVT::i8: ObjSize = 1; break; - case MVT::i16: ObjSize = 2; break; - case MVT::i32: ObjSize = 4; break; - case MVT::i64: ObjSize = ArgIncrement = 8; break; - case MVT::f32: ObjSize = 4; break; - case MVT::f64: ObjSize = ArgIncrement = 8; break; - } - // Create the frame index object for this incoming parameter... - int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); - - // Create the SelectionDAG nodes corresponding to a load from this parameter - SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); - - // Don't codegen dead arguments. FIXME: remove this check when we can nuke - // dead loads. - SDOperand ArgValue; - if (!I->use_empty()) - ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN, - DAG.getSrcValue(NULL)); - else { - if (MVT::isInteger(ObjectVT)) - ArgValue = DAG.getConstant(0, ObjectVT); - else - ArgValue = DAG.getConstantFP(0, ObjectVT); - } - ArgValues.push_back(ArgValue); - - ArgOffset += ArgIncrement; // Move on to the next argument... - } - - // If the function takes variable number of arguments, make a frame index for - // the start of the first vararg value... for expansion of llvm.va_start. - if (F.isVarArg()) - VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset); - ReturnAddrIndex = 0; // No return address slot generated yet. - BytesToPopOnReturn = 0; // Callee pops nothing. - BytesCallerReserves = ArgOffset; - - // Finally, inform the code generator which regs we return values in. - switch (getValueType(F.getReturnType())) { - default: assert(0 && "Unknown type!"); - case MVT::isVoid: break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - MF.addLiveOut(X86::EAX); - break; - case MVT::i64: - MF.addLiveOut(X86::EAX); - MF.addLiveOut(X86::EDX); - break; - case MVT::f32: - case MVT::f64: - MF.addLiveOut(X86::ST0); - break; - } - return ArgValues; -} - -std::pair -X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy, - bool isVarArg, bool isTailCall, - SDOperand Callee, ArgListTy &Args, - SelectionDAG &DAG) { - // Count how many bytes are to be pushed on the stack. - unsigned NumBytes = 0; - - if (Args.empty()) { - // Save zero bytes. - Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, - DAG.getConstant(0, getPointerTy())); - } else { - for (unsigned i = 0, e = Args.size(); i != e; ++i) - switch (getValueType(Args[i].second)) { - default: assert(0 && "Unknown value type!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::f32: - NumBytes += 4; - break; - case MVT::i64: - case MVT::f64: - NumBytes += 8; - break; - } - - Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, - DAG.getConstant(NumBytes, getPointerTy())); - - // Arguments go on the stack in reverse order, as specified by the ABI. - unsigned ArgOffset = 0; - SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(), - X86::ESP, MVT::i32); - std::vector Stores; - - for (unsigned i = 0, e = Args.size(); i != e; ++i) { - SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); - - switch (getValueType(Args[i].second)) { - default: assert(0 && "Unexpected ValueType for argument!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - // Promote the integer to 32 bits. If the input type is signed use a - // sign extend, otherwise use a zero extend. - if (Args[i].second->isSigned()) - Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first); - else - Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first); - - // FALL THROUGH - case MVT::i32: - case MVT::f32: - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); - ArgOffset += 4; - break; - case MVT::i64: - case MVT::f64: - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); - ArgOffset += 8; - break; - } - } - Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores); - } - - std::vector RetVals; - MVT::ValueType RetTyVT = getValueType(RetTy); - RetVals.push_back(MVT::Other); - - // The result values produced have to be legal. Promote the result. - switch (RetTyVT) { - case MVT::isVoid: break; - default: - RetVals.push_back(RetTyVT); - break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - RetVals.push_back(MVT::i32); - break; - case MVT::f32: - if (X86ScalarSSE) - RetVals.push_back(MVT::f32); - else - RetVals.push_back(MVT::f64); - break; - case MVT::i64: - RetVals.push_back(MVT::i32); - RetVals.push_back(MVT::i32); - break; - } - std::vector Ops; - Ops.push_back(Chain); - Ops.push_back(Callee); - Ops.push_back(DAG.getConstant(NumBytes, getPointerTy())); - Ops.push_back(DAG.getConstant(0, getPointerTy())); - SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, - RetVals, Ops); - Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall); - - SDOperand ResultVal; - switch (RetTyVT) { - case MVT::isVoid: break; - default: - ResultVal = TheCall.getValue(1); - break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1)); - break; - case MVT::f32: - // FIXME: we would really like to remember that this FP_ROUND operation is - // okay to eliminate if we allow excess FP precision. - ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1)); - break; - case MVT::i64: - ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1), - TheCall.getValue(2)); - break; - } - - return std::make_pair(ResultVal, Chain); -} - -SDOperand -X86TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG) { - // vastart just stores the address of the VarArgsFrameIndex slot. - SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); - return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, - DAG.getSrcValue(VAListV)); -} - - -std::pair -X86TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, - Value *VAListV, const Type *ArgTy, - SelectionDAG &DAG) { - MVT::ValueType ArgVT = getValueType(ArgTy); - SDOperand Val = DAG.getLoad(MVT::i32, Chain, - VAListP, DAG.getSrcValue(VAListV)); - SDOperand Result = DAG.getLoad(ArgVT, Chain, Val, - DAG.getSrcValue(NULL)); - unsigned Amt; - if (ArgVT == MVT::i32) - Amt = 4; - else { - assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && - "Other types should have been promoted for varargs!"); - Amt = 8; - } - Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val, - DAG.getConstant(Amt, Val.getValueType())); - Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, - Val, VAListP, DAG.getSrcValue(VAListV)); - return std::make_pair(Result, Chain); -} - -//===----------------------------------------------------------------------===// -// Fast Calling Convention implementation -//===----------------------------------------------------------------------===// -// -// The X86 'fast' calling convention passes up to two integer arguments in -// registers (an appropriate portion of EAX/EDX), passes arguments in C order, -// and requires that the callee pop its arguments off the stack (allowing proper -// tail calls), and has the same return value conventions as C calling convs. -// -// This calling convention always arranges for the callee pop value to be 8n+4 -// bytes, which is needed for tail recursion elimination and stack alignment -// reasons. -// -// Note that this can be enhanced in the future to pass fp vals in registers -// (when we have a global fp allocator) and do other tricks. -// - -/// AddLiveIn - This helper function adds the specified physical register to the -/// MachineFunction as a live in value. It also creates a corresponding virtual -/// register for it. -static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg, - TargetRegisterClass *RC) { - assert(RC->contains(PReg) && "Not the correct regclass!"); - unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC); - MF.addLiveIn(PReg, VReg); - return VReg; -} - - -std::vector -X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) { - std::vector ArgValues; - - MachineFunction &MF = DAG.getMachineFunction(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - - // Add DAG nodes to load the arguments... On entry to a function the stack - // frame looks like this: - // - // [ESP] -- return address - // [ESP + 4] -- first nonreg argument (leftmost lexically) - // [ESP + 8] -- second nonreg argument, if first argument is 4 bytes in size - // ... - unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot - - // Keep track of the number of integer regs passed so far. This can be either - // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both - // used). - unsigned NumIntRegs = 0; - - for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { - MVT::ValueType ObjectVT = getValueType(I->getType()); - unsigned ArgIncrement = 4; - unsigned ObjSize = 0; - SDOperand ArgValue; - - switch (ObjectVT) { - default: assert(0 && "Unhandled argument type!"); - case MVT::i1: - case MVT::i8: - if (NumIntRegs < 2) { - if (!I->use_empty()) { - unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DL : X86::AL, - X86::R8RegisterClass); - ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i8); - DAG.setRoot(ArgValue.getValue(1)); - } - ++NumIntRegs; - break; - } - - ObjSize = 1; - break; - case MVT::i16: - if (NumIntRegs < 2) { - if (!I->use_empty()) { - unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DX : X86::AX, - X86::R16RegisterClass); - ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i16); - DAG.setRoot(ArgValue.getValue(1)); - } - ++NumIntRegs; - break; - } - ObjSize = 2; - break; - case MVT::i32: - if (NumIntRegs < 2) { - if (!I->use_empty()) { - unsigned VReg = AddLiveIn(MF,NumIntRegs ? X86::EDX : X86::EAX, - X86::R32RegisterClass); - ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32); - DAG.setRoot(ArgValue.getValue(1)); - } - ++NumIntRegs; - break; - } - ObjSize = 4; - break; - case MVT::i64: - if (NumIntRegs == 0) { - if (!I->use_empty()) { - unsigned BotReg = AddLiveIn(MF, X86::EAX, X86::R32RegisterClass); - unsigned TopReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass); - - SDOperand Low = DAG.getCopyFromReg(DAG.getRoot(), BotReg, MVT::i32); - SDOperand Hi = DAG.getCopyFromReg(Low.getValue(1), TopReg, MVT::i32); - DAG.setRoot(Hi.getValue(1)); - - ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Low, Hi); - } - NumIntRegs = 2; - break; - } else if (NumIntRegs == 1) { - if (!I->use_empty()) { - unsigned BotReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass); - SDOperand Low = DAG.getCopyFromReg(DAG.getRoot(), BotReg, MVT::i32); - DAG.setRoot(Low.getValue(1)); - - // Load the high part from memory. - // Create the frame index object for this incoming parameter... - int FI = MFI->CreateFixedObject(4, ArgOffset); - SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); - SDOperand Hi = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN, - DAG.getSrcValue(NULL)); - ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Low, Hi); - } - ArgOffset += 4; - NumIntRegs = 2; - break; - } - ObjSize = ArgIncrement = 8; - break; - case MVT::f32: ObjSize = 4; break; - case MVT::f64: ObjSize = ArgIncrement = 8; break; - } - - // Don't codegen dead arguments. FIXME: remove this check when we can nuke - // dead loads. - if (ObjSize && !I->use_empty()) { - // Create the frame index object for this incoming parameter... - int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); - - // Create the SelectionDAG nodes corresponding to a load from this - // parameter. - SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); - - ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN, - DAG.getSrcValue(NULL)); - } else if (ArgValue.Val == 0) { - if (MVT::isInteger(ObjectVT)) - ArgValue = DAG.getConstant(0, ObjectVT); - else - ArgValue = DAG.getConstantFP(0, ObjectVT); - } - ArgValues.push_back(ArgValue); - - if (ObjSize) - ArgOffset += ArgIncrement; // Move on to the next argument. - } - - // Make sure the instruction takes 8n+4 bytes to make sure the start of the - // arguments and the arguments after the retaddr has been pushed are aligned. - if ((ArgOffset & 7) == 0) - ArgOffset += 4; - - VarArgsFrameIndex = 0xAAAAAAA; // fastcc functions can't have varargs. - ReturnAddrIndex = 0; // No return address slot generated yet. - BytesToPopOnReturn = ArgOffset; // Callee pops all stack arguments. - BytesCallerReserves = 0; - - // Finally, inform the code generator which regs we return values in. - switch (getValueType(F.getReturnType())) { - default: assert(0 && "Unknown type!"); - case MVT::isVoid: break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - MF.addLiveOut(X86::EAX); - break; - case MVT::i64: - MF.addLiveOut(X86::EAX); - MF.addLiveOut(X86::EDX); - break; - case MVT::f32: - case MVT::f64: - MF.addLiveOut(X86::ST0); - break; - } - return ArgValues; -} - -std::pair -X86TargetLowering::LowerFastCCCallTo(SDOperand Chain, const Type *RetTy, - bool isTailCall, SDOperand Callee, - ArgListTy &Args, SelectionDAG &DAG) { - // Count how many bytes are to be pushed on the stack. - unsigned NumBytes = 0; - - // Keep track of the number of integer regs passed so far. This can be either - // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both - // used). - unsigned NumIntRegs = 0; - - for (unsigned i = 0, e = Args.size(); i != e; ++i) - switch (getValueType(Args[i].second)) { - default: assert(0 && "Unknown value type!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - if (NumIntRegs < 2) { - ++NumIntRegs; - break; - } - // fall through - case MVT::f32: - NumBytes += 4; - break; - case MVT::i64: - if (NumIntRegs == 0) { - NumIntRegs = 2; - break; - } else if (NumIntRegs == 1) { - NumIntRegs = 2; - NumBytes += 4; - break; - } - - // fall through - case MVT::f64: - NumBytes += 8; - break; - } - - // Make sure the instruction takes 8n+4 bytes to make sure the start of the - // arguments and the arguments after the retaddr has been pushed are aligned. - if ((NumBytes & 7) == 0) - NumBytes += 4; - - Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, - DAG.getConstant(NumBytes, getPointerTy())); - - // Arguments go on the stack in reverse order, as specified by the ABI. - unsigned ArgOffset = 0; - SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(), - X86::ESP, MVT::i32); - NumIntRegs = 0; - std::vector Stores; - std::vector RegValuesToPass; - for (unsigned i = 0, e = Args.size(); i != e; ++i) { - switch (getValueType(Args[i].second)) { - default: assert(0 && "Unexpected ValueType for argument!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - if (NumIntRegs < 2) { - RegValuesToPass.push_back(Args[i].first); - ++NumIntRegs; - break; - } - // Fall through - case MVT::f32: { - SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); - ArgOffset += 4; - break; - } - case MVT::i64: - if (NumIntRegs < 2) { // Can pass part of it in regs? - SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, - Args[i].first, DAG.getConstant(1, MVT::i32)); - SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, - Args[i].first, DAG.getConstant(0, MVT::i32)); - RegValuesToPass.push_back(Lo); - ++NumIntRegs; - if (NumIntRegs < 2) { // Pass both parts in regs? - RegValuesToPass.push_back(Hi); - ++NumIntRegs; - } else { - // Pass the high part in memory. - SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Hi, PtrOff, DAG.getSrcValue(NULL))); - ArgOffset += 4; - } - break; - } - // Fall through - case MVT::f64: - SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); - ArgOffset += 8; - break; - } - } - if (!Stores.empty()) - Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores); - - // Make sure the instruction takes 8n+4 bytes to make sure the start of the - // arguments and the arguments after the retaddr has been pushed are aligned. - if ((ArgOffset & 7) == 0) - ArgOffset += 4; - - std::vector RetVals; - MVT::ValueType RetTyVT = getValueType(RetTy); - - RetVals.push_back(MVT::Other); - - // The result values produced have to be legal. Promote the result. - switch (RetTyVT) { - case MVT::isVoid: break; - default: - RetVals.push_back(RetTyVT); - break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - RetVals.push_back(MVT::i32); - break; - case MVT::f32: - if (X86ScalarSSE) - RetVals.push_back(MVT::f32); - else - RetVals.push_back(MVT::f64); - break; - case MVT::i64: - RetVals.push_back(MVT::i32); - RetVals.push_back(MVT::i32); - break; - } - - std::vector Ops; - Ops.push_back(Chain); - Ops.push_back(Callee); - Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy())); - // Callee pops all arg values on the stack. - Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy())); - - // Pass register arguments as needed. - Ops.insert(Ops.end(), RegValuesToPass.begin(), RegValuesToPass.end()); - - SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, - RetVals, Ops); - Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall); - - SDOperand ResultVal; - switch (RetTyVT) { - case MVT::isVoid: break; - default: - ResultVal = TheCall.getValue(1); - break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1)); - break; - case MVT::f32: - // FIXME: we would really like to remember that this FP_ROUND operation is - // okay to eliminate if we allow excess FP precision. - ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1)); - break; - case MVT::i64: - ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1), - TheCall.getValue(2)); - break; - } - - return std::make_pair(ResultVal, Chain); -} - -SDOperand X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) { - if (ReturnAddrIndex == 0) { - // Set up a frame object for the return address. - MachineFunction &MF = DAG.getMachineFunction(); - ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(4, -4); - } - - return DAG.getFrameIndex(ReturnAddrIndex, MVT::i32); -} - - - -std::pair X86TargetLowering:: -LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, - SelectionDAG &DAG) { - SDOperand Result; - if (Depth) // Depths > 0 not supported yet! - Result = DAG.getConstant(0, getPointerTy()); - else { - SDOperand RetAddrFI = getReturnAddressFrameIndex(DAG); - if (!isFrameAddress) - // Just load the return address - Result = DAG.getLoad(MVT::i32, DAG.getEntryNode(), RetAddrFI, - DAG.getSrcValue(NULL)); - else - Result = DAG.getNode(ISD::SUB, MVT::i32, RetAddrFI, - DAG.getConstant(4, MVT::i32)); - } - return std::make_pair(Result, Chain); -} - -//===----------------------------------------------------------------------===// -// X86 Custom Lowering Hooks -//===----------------------------------------------------------------------===// - -/// LowerOperation - Provide custom lowering hooks for some operations. -/// -SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { - switch (Op.getOpcode()) { - default: assert(0 && "Should not custom lower this!"); - case ISD::SINT_TO_FP: { - assert(Op.getValueType() == MVT::f64 && - Op.getOperand(0).getValueType() == MVT::i64 && - "Unknown SINT_TO_FP to lower!"); - // We lower sint64->FP into a store to a temporary stack slot, followed by a - // FILD64m node. - MachineFunction &MF = DAG.getMachineFunction(); - int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8); - SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); - SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), - Op.getOperand(0), StackSlot, DAG.getSrcValue(NULL)); - std::vector RTs; - RTs.push_back(MVT::f64); - RTs.push_back(MVT::Other); - std::vector Ops; - Ops.push_back(Store); - Ops.push_back(StackSlot); - return DAG.getNode(X86ISD::FILD64m, RTs, Ops); - } - case ISD::FP_TO_SINT: { - assert(Op.getValueType() <= MVT::i64 && Op.getValueType() >= MVT::i16 && - Op.getOperand(0).getValueType() == MVT::f64 && - "Unknown FP_TO_SINT to lower!"); - // We lower FP->sint64 into FISTP64, followed by a load, all to a temporary - // stack slot. - MachineFunction &MF = DAG.getMachineFunction(); - unsigned MemSize = MVT::getSizeInBits(Op.getValueType())/8; - int SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize); - SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); - - unsigned Opc; - switch (Op.getValueType()) { - default: assert(0 && "Invalid FP_TO_SINT to lower!"); - case MVT::i16: Opc = X86ISD::FP_TO_INT16_IN_MEM; break; - case MVT::i32: Opc = X86ISD::FP_TO_INT32_IN_MEM; break; - case MVT::i64: Opc = X86ISD::FP_TO_INT64_IN_MEM; break; - } - - // Build the FP_TO_INT*_IN_MEM - std::vector Ops; - Ops.push_back(DAG.getEntryNode()); - Ops.push_back(Op.getOperand(0)); - Ops.push_back(StackSlot); - SDOperand FIST = DAG.getNode(Opc, MVT::Other, Ops); - - // Load the result. - return DAG.getLoad(Op.getValueType(), FIST, StackSlot, - DAG.getSrcValue(NULL)); - } - } -} - - //===----------------------------------------------------------------------===// // Pattern Matcher Implementation //===----------------------------------------------------------------------===// @@ -4635,10 +3636,10 @@ } -/// createX86PatternInstructionSelector - This pass converts an LLVM function +/// createX86ISelPattern - This pass converts an LLVM function /// into a machine code representation using pattern matching and a machine /// description file. /// -FunctionPass *llvm::createX86PatternInstructionSelector(TargetMachine &TM) { +FunctionPass *llvm::createX86ISelPattern(TargetMachine &TM) { return new ISel(TM); } Index: llvm/lib/Target/X86/X86TargetMachine.cpp diff -u llvm/lib/Target/X86/X86TargetMachine.cpp:1.87 llvm/lib/Target/X86/X86TargetMachine.cpp:1.88 --- llvm/lib/Target/X86/X86TargetMachine.cpp:1.87 Mon Nov 7 20:11:51 2005 +++ llvm/lib/Target/X86/X86TargetMachine.cpp Mon Nov 14 18:40:24 2005 @@ -124,7 +124,7 @@ PM.add(createUnreachableBlockEliminationPass()); // Install an instruction selector. - PM.add(createX86PatternInstructionSelector(*this)); + PM.add(createX86ISelPattern(*this)); // Run optional SSA-based machine code optimizations next... if (!NoSSAPeephole) @@ -192,7 +192,7 @@ PM.add(createUnreachableBlockEliminationPass()); // Install an instruction selector. - PM.add(createX86PatternInstructionSelector(TM)); + PM.add(createX86ISelPattern(TM)); // Run optional SSA-based machine code optimizations next... if (!NoSSAPeephole) From lattner at cs.uiuc.edu Mon Nov 14 19:32:14 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 14 Nov 2005 19:32:14 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Mangler.cpp Message-ID: <200511150132.TAA27383@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Mangler.cpp updated: 1.25 -> 1.26 --- Log message: Fix handling of multiple unnamed globals with the same type --- Diffs of the changes: (+6 -3) Mangler.cpp | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) Index: llvm/lib/VMCore/Mangler.cpp diff -u llvm/lib/VMCore/Mangler.cpp:1.25 llvm/lib/VMCore/Mangler.cpp:1.26 --- llvm/lib/VMCore/Mangler.cpp:1.25 Thu Nov 10 17:24:26 2005 +++ llvm/lib/VMCore/Mangler.cpp Mon Nov 14 19:32:03 2005 @@ -132,6 +132,11 @@ // - Otherwise, mangling occurs if global collides with existing name. if (isa(GV) && cast(GV)->getIntrinsicID()) { Name = GV->getName(); // Is an intrinsic function + } else if (!GV->hasName()) { + // Must mangle the global into a unique ID. + unsigned TypeUniqueID = getTypeID(GV->getType()); + static unsigned GlobalID = 0; + Name = "__unnamed_" + utostr(TypeUniqueID) + "_" + utostr(GlobalID++); } else if (!MangledGlobals.count(GV)) { Name = makeNameProper(GV->getName(), Prefix); } else { @@ -144,10 +149,8 @@ void Mangler::InsertName(GlobalValue *GV, std::map &Names) { - if (!GV->hasName()) { // We must mangle unnamed globals. - MangledGlobals.insert(GV); + if (!GV->hasName()) // We must mangle unnamed globals. return; - } // Figure out if this is already used. GlobalValue *&ExistingValue = Names[GV->getName()]; From lattner at cs.uiuc.edu Mon Nov 14 19:45:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 14 Nov 2005 19:45:12 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Message-ID: <200511150145.TAA27479@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.108 -> 1.109 --- Log message: Make sure to use SwitchSection to switch sections so that we don't accidentally emit functions into the .const section. Whoops. --- Diffs of the changes: (+3 -2) PPCAsmPrinter.cpp | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.108 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.109 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.108 Mon Nov 14 13:00:30 2005 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Mon Nov 14 19:45:01 2005 @@ -437,7 +437,7 @@ if (CP.empty()) return; for (unsigned i = 0, e = CP.size(); i != e; ++i) { - O << "\t.const\n"; + SwitchSection(".const", 0); // FIXME: force doubles to be naturally aligned. We should handle this // more correctly in the future. if (Type::DoubleTy == CP[i]->getType()) @@ -487,6 +487,7 @@ } else { switch (I->getLinkage()) { case GlobalValue::LinkOnceLinkage: + SwitchSection("", 0); O << ".section __TEXT,__textcoal_nt,coalesced,no_toc\n" << ".weak_definition " << name << '\n' << ".private_extern " << name << '\n' @@ -649,7 +650,7 @@ if (CP.empty()) return; for (unsigned i = 0, e = CP.size(); i != e; ++i) { - O << "\t.const\n"; + SwitchSection(".const", 0); O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType()) << "\n"; O << "LCPI" << FunctionNumber << '_' << i << ":\t\t\t\t\t;" From lattner at cs.uiuc.edu Tue Nov 15 00:08:07 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 15 Nov 2005 00:08:07 -0600 Subject: [llvm-commits] CVS: llvm/docs/LangRef.html Message-ID: <200511150608.AAA28758@zion.cs.uiuc.edu> Changes in directory llvm/docs: LangRef.html updated: 1.118 -> 1.119 --- Log message: Fix some typos noticed by Gabor Greif! --- Diffs of the changes: (+2 -2) LangRef.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/docs/LangRef.html diff -u llvm/docs/LangRef.html:1.118 llvm/docs/LangRef.html:1.119 --- llvm/docs/LangRef.html:1.118 Fri Nov 11 18:45:07 2005 +++ llvm/docs/LangRef.html Tue Nov 15 00:07:55 2005 @@ -2799,7 +2799,7 @@ code to simulators and other tools. The method is target specific, but it is expected that the marker will use exported symbols to transmit the PC of the marker. The marker makes no guarantees that it will remain with any specific instruction -after optimizations. It is possible that the presense of a marker will inhibit +after optimizations. It is possible that the presence of a marker will inhibit optimizations. The intended use is to be inserted after optmizations to allow correlations of simulation runs.

@@ -3429,7 +3429,7 @@ Chris Lattner
The LLVM Compiler Infrastructure
- Last modified: $Date: 2005/11/12 00:45:07 $ + Last modified: $Date: 2005/11/15 06:07:55 $ From lattner at cs.uiuc.edu Tue Nov 15 00:44:27 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 15 Nov 2005 00:44:27 -0600 Subject: [llvm-commits] CVS: llvm/utils/NightlyTest.gnuplot Message-ID: <200511150644.AAA28972@zion.cs.uiuc.edu> Changes in directory llvm/utils: NightlyTest.gnuplot updated: 1.14 -> 1.15 --- Log message: remove these labels, there are now bigger jumps in the graph that are unlabeled --- Diffs of the changes: (+0 -9) NightlyTest.gnuplot | 9 --------- 1 files changed, 9 deletions(-) Index: llvm/utils/NightlyTest.gnuplot diff -u llvm/utils/NightlyTest.gnuplot:1.14 llvm/utils/NightlyTest.gnuplot:1.15 --- llvm/utils/NightlyTest.gnuplot:1.14 Fri Oct 28 11:35:18 2005 +++ llvm/utils/NightlyTest.gnuplot Tue Nov 15 00:44:15 2005 @@ -8,15 +8,6 @@ set timefmt "%Y-%m-%d-%H:%M:%S:" set format x "%b %d, %Y" -## Various labels for the graph -set label "Reoptimizer\n checkins" at "2003-02-18:", 114000 -set label "Modulo Sched\n checkin" at "2003-03-28:", 119500 -set label "Reoptimizer\n checkins" at "2003-06-01:", 134000 -set label "'dummy'\nfunction" at "2003-07-20:", 150000 -set label "Reoptimizer\n removal" at "2003-08-10:", 132000 -set label "llvm-db\ncheckin" at "2004-01-04:", 145000 -set label "llvm/projects" at "2004-01-04:", 151000 - set size .75,.75 set xtics rotate set xlabel 0,-1 From jeffc at jolt-lang.org Tue Nov 15 10:12:07 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Tue, 15 Nov 2005 10:12:07 -0600 Subject: [llvm-commits] CVS: llvm/win32/x86/x86.vcproj Message-ID: <200511151612.KAA30106@zion.cs.uiuc.edu> Changes in directory llvm/win32/x86: x86.vcproj updated: 1.14 -> 1.15 --- Log message: Keep Visual Studio informed of new files. --- Diffs of the changes: (+6 -0) x86.vcproj | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/win32/x86/x86.vcproj diff -u llvm/win32/x86/x86.vcproj:1.14 llvm/win32/x86/x86.vcproj:1.15 --- llvm/win32/x86/x86.vcproj:1.14 Fri Aug 19 08:51:22 2005 +++ llvm/win32/x86/x86.vcproj Tue Nov 15 10:11:55 2005 @@ -164,6 +164,9 @@ RelativePath="..\..\lib\Target\X86\X86IntelAsmPrinter.cpp"> + + + + Changes in directory llvm: Makefile updated: 1.51.2.1 -> 1.51.2.2 --- Log message: Added examples to built directories --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/Makefile diff -u llvm/Makefile:1.51.2.1 llvm/Makefile:1.51.2.2 --- llvm/Makefile:1.51.2.1 Tue Oct 18 14:21:38 2005 +++ llvm/Makefile Tue Nov 15 14:13:38 2005 @@ -14,7 +14,7 @@ else ifneq ($(MAKECMDGOALS),libs-only) DIRS += tools runtime docs - OPTIONAL_DIRS = #projects + OPTIONAL_DIRS = examples #projects endif endif From bocchino at persephone.cs.uiuc.edu Tue Nov 15 14:16:03 2005 From: bocchino at persephone.cs.uiuc.edu (Robert L. Bocchino Jr.) Date: Tue, 15 Nov 2005 14:16:03 -0600 (CST) Subject: [llvm-commits] [vector_llvm] CVS: llvm/include/VectorLLVM/VectorSignificantFunctions.h Message-ID: <20051115201603.BE92119ADED8@persephone.cs.uiuc.edu> Changes in directory llvm/include/VectorLLVM: VectorSignificantFunctions.h updated: 1.1.2.1 -> 1.1.2.2 --- Log message: Updated the signature for extract --- Diffs of the changes: (+2 -2) VectorSignificantFunctions.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/include/VectorLLVM/VectorSignificantFunctions.h diff -u llvm/include/VectorLLVM/VectorSignificantFunctions.h:1.1.2.1 llvm/include/VectorLLVM/VectorSignificantFunctions.h:1.1.2.2 --- llvm/include/VectorLLVM/VectorSignificantFunctions.h:1.1.2.1 Tue Oct 18 14:35:24 2005 +++ llvm/include/VectorLLVM/VectorSignificantFunctions.h Tue Nov 15 14:14:14 2005 @@ -189,13 +189,13 @@ break; case extract: // An extract function must have precisely 4 arguments: a value - // and 3 unsigned ints + // an unsigned int, and int, and an unsigned int // if (numParams != 4 || isVarArg) return false; if (FTy->getParamType(1) != Type::UIntTy) return false; - if (FTy->getParamType(2) != Type::UIntTy) + if (!FTy->getParamType(2)->isIntegral()) return false; if (FTy->getParamType(3) != Type::UIntTy) return false; From bocchino at persephone.cs.uiuc.edu Tue Nov 15 14:16:03 2005 From: bocchino at persephone.cs.uiuc.edu (Robert L. Bocchino Jr.) Date: Tue, 15 Nov 2005 14:16:03 -0600 (CST) Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Transforms/Vector/AltiVec.cpp LowerVectors.cpp RaiseVectors.cpp SSE.cpp Message-ID: <20051115201603.BD68419ADED7@persephone.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Vector: AltiVec.cpp updated: 1.1.2.1 -> 1.1.2.2 LowerVectors.cpp updated: 1.1.2.1 -> 1.1.2.2 RaiseVectors.cpp updated: 1.1.2.1 -> 1.1.2.2 SSE.cpp updated: 1.1.2.1 -> 1.1.2.2 --- Log message: Improved AltiVec code generation support Changed the signature for extract Made lowervectors work with fixed vectors --- Diffs of the changes: (+108 -131) AltiVec.cpp | 103 +++++++++++++++++++++++++------------------------------ LowerVectors.cpp | 62 ++++++++++++++++++++++++++++----- RaiseVectors.cpp | 9 +++- SSE.cpp | 65 ---------------------------------- 4 files changed, 108 insertions(+), 131 deletions(-) Index: llvm/lib/Transforms/Vector/AltiVec.cpp diff -u llvm/lib/Transforms/Vector/AltiVec.cpp:1.1.2.1 llvm/lib/Transforms/Vector/AltiVec.cpp:1.1.2.2 --- llvm/lib/Transforms/Vector/AltiVec.cpp:1.1.2.1 Tue Oct 18 14:37:03 2005 +++ llvm/lib/Transforms/Vector/AltiVec.cpp Tue Nov 15 14:15:33 2005 @@ -41,7 +41,6 @@ public: bool runOnFunction(Function &F); - void visitCastInst(CastInst &); void visitVImmInst(VImmInst &); void visitExtractInst(ExtractInst &); void visitCombineInst(CombineInst &); @@ -103,7 +102,6 @@ return "altivec_" + baseName + "_" + VT->getElementType()->getDescription(); } - //===----------------------------------------------------------------------===// // AltiVec implementation //===----------------------------------------------------------------------===// @@ -114,13 +112,15 @@ instructionsToDelete.clear(); changed = false; for (Function::iterator FI = F.begin(), FE = F.end(); - FI != FE; ++FI) + FI != FE; ++FI) { for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); - BI != BE; ++BI) + BI != BE; ++BI) { if (!instructionsToDelete.count(BI)) { DEBUG(std::cerr << "Visiting instruction " << *BI); visit(*BI); } + } + } if (changed) deleteInstructions(); return changed; } @@ -157,35 +157,6 @@ changed = true; } - void AltiVec::visitCastInst(CastInst &CI) { - // We need only worry about a cast of a non-constant scalar to a - // vector; the AltiVec C Backend can handle the other cases - // directly. - // - const VectorType *VT = dyn_cast(CI.getType()); - if (!VT || !isProperType(VT) || - isa(CI.getOperand(0)->getType()) || - isa(CI.getOperand(0))) - return; - // We need to create a new vector on the stack, store the scalar - // value into it, and splat the value into a vector register - // - AllocaInst *vectorPtr = new AllocaInst(VT, 0, "alloca", &CI); - Value *element = CI.getOperand(0); - if (element->getType() != VT->getElementType()) - element = new CastInst(element, VT->getElementType(), "cast", &CI); - CastInst *scalarPtr = new CastInst(vectorPtr, PointerType::get(VT->getElementType()), - "cast", &CI); - StoreInst *store = new StoreInst(element, scalarPtr, &CI); - LoadInst *vector = new LoadInst(vectorPtr, "load", &CI); - CallInst *call = VectorUtils::getCallInst(VT, getAltiVecName("splat", VT), - vector, ConstantUInt::get(Type::UByteTy, 0), - "splat", &CI); - CI.replaceAllUsesWith(call); - instructionsToDelete.insert(&CI); - changed = true; - } - // Check whether an extract instruction should be turned into // altivec_unpack // @@ -403,7 +374,7 @@ CastInst *addCast0 = 0, *addCast2 = 0, *shrCast = 0; VImmInst *VImm = 0; ShiftInst *shr = 0; - CallInst *adds; + CallInst *adds = 0; unsigned offset = 0, shamt = 0; if (&BO == add->getOperand(0)) addCast0 = dyn_cast(add->getOperand(1)); @@ -427,30 +398,52 @@ } if (shrCast && shrCast->hasOneUse()) { adds = dyn_cast(*shrCast->use_begin()); - Function *F = adds->getCalledFunction(); - if (!F || F->getName().substr(0, 10) != "vllvm_adds") + if (adds) { + Function *F = adds->getCalledFunction(); + if (!F || F->getName().substr(0, 10) != "vllvm_adds") adds = 0; + } } if (mulCast0 && mulCast1 && addCast0 && VImm && - offset == 16384 && shrCast && shr && shamt == 15 && - adds) { - VT = cast(adds->getType()); - CallInst *mradds = VectorUtils::getCallInst(VT, getAltiVecName("mradds", VT), - new CastInst(mulCast0->getOperand(0), VT, "cast", adds), - new CastInst(mulCast1->getOperand(0), VT, "cast", adds), - (shrCast == adds->getOperand(1)) ? adds->getOperand(2) : adds->getOperand(1), - "mradds", adds); - adds->replaceAllUsesWith(mradds); - instructionsToDelete.insert(&BO); - instructionsToDelete.insert(add); - instructionsToDelete.insert(shr); - instructionsToDelete.insert(mulCast0); - instructionsToDelete.insert(mulCast1); - instructionsToDelete.insert(addCast0); - instructionsToDelete.insert(VImm); - instructionsToDelete.insert(shrCast); - instructionsToDelete.insert(adds); - changed = true; + offset == 16384 && shrCast && shr && shamt == 15) { + if (adds) { + VT = cast(adds->getType()); + CallInst *mradds = VectorUtils::getCallInst(VT, getAltiVecName("mradds", VT), + new CastInst(mulCast0->getOperand(0), VT, "cast", adds), + new CastInst(mulCast1->getOperand(0), VT, "cast", adds), + (shrCast == adds->getOperand(1)) ? adds->getOperand(2) : adds->getOperand(1), + "mradds", adds); + adds->replaceAllUsesWith(mradds); + instructionsToDelete.insert(&BO); + instructionsToDelete.insert(add); + instructionsToDelete.insert(shr); + instructionsToDelete.insert(mulCast0); + instructionsToDelete.insert(mulCast1); + instructionsToDelete.insert(addCast0); + instructionsToDelete.insert(VImm); + instructionsToDelete.insert(shrCast); + instructionsToDelete.insert(adds); + changed = true; + } else { + VT = cast(shrCast->getType()); + CallInst *mradds = VectorUtils::getCallInst(VT, getAltiVecName("mradds", VT), + new CastInst(mulCast0->getOperand(0), VT, "cast", shrCast), + new CastInst(mulCast1->getOperand(0), VT, "cast", shrCast), + new VImmInst(Constant::getNullValue(VT->getElementType()), + ConstantUInt::get(Type::UIntTy, VT->getNumElements()), + true, "vimm", shrCast), + "mradds", shrCast); + shrCast->replaceAllUsesWith(mradds); + instructionsToDelete.insert(&BO); + instructionsToDelete.insert(add); + instructionsToDelete.insert(shr); + instructionsToDelete.insert(mulCast0); + instructionsToDelete.insert(mulCast1); + instructionsToDelete.insert(addCast0); + instructionsToDelete.insert(VImm); + instructionsToDelete.insert(shrCast); + changed = true; + } return; } // Check for mladd pattern Index: llvm/lib/Transforms/Vector/LowerVectors.cpp diff -u llvm/lib/Transforms/Vector/LowerVectors.cpp:1.1.2.1 llvm/lib/Transforms/Vector/LowerVectors.cpp:1.1.2.2 --- llvm/lib/Transforms/Vector/LowerVectors.cpp:1.1.2.1 Tue Oct 18 14:37:03 2005 +++ llvm/lib/Transforms/Vector/LowerVectors.cpp Tue Nov 15 14:15:33 2005 @@ -63,6 +63,7 @@ void visitFreeInst(FreeInst&); void visitStoreInst(StoreInst&); void visitLoadInst(LoadInst&); + void visitGetElementPtrInst(GetElementPtrInst&); void visitInstruction(Instruction& I) { std::cerr << "LowerVectors class can't handle instruction " << I << "!\n"; exit(1); @@ -110,7 +111,7 @@ class InstructionLowering : public InstVisitor { friend class LowerVectors; - Instruction *vector; + Value *vector; Value *result, *vectorIndex; std::vector idx; BasicBlock *body; @@ -219,6 +220,8 @@ /// Given a vector type value, look in the lengthMap to get its length. /// Value *getLength(Value *key) { + if (const FixedVectorType *VT = dyn_cast(key->getType())) + return ConstantUInt::get(Type::UIntTy, VT->getNumElements()); Value*& V = lengthMap[key]; if (!V) { V = new Argument(Type::UIntTy); @@ -248,6 +251,9 @@ /// type to the same type. /// const Type* getLoweredMemoryType(const Type* Ty) { + if (const FixedVectorType *VT = dyn_cast(Ty)) { + return VT->getElementType(); + } if (const VectorType *VectorTy = dyn_cast(Ty)) { std::vector Params; Params.push_back(PointerType::get(VectorTy->getElementType())); @@ -284,7 +290,10 @@ /// lowered. /// Value *getLoweredValue(Value *key) { - const VectorType *VectorTy = dyn_cast(key->getType()); + if (!VectorUtils::containsVector(key->getType()) && + !isa(key)) { + return key; + } Value*& value = loweringMap[key]; if (!value) { value = new Argument(getLoweredRegisterType(key->getType())); @@ -501,9 +510,29 @@ } void LowerVectors::visitCastInst(CastInst &CI) { - InstructionLowering lower(&CI, getLength(CI.getOperand(0))); + if (isa(CI.getType())) { + CastInst *Cast = + new CastInst(getLoweredValue(CI.getOperand(0)), + getLoweredMemoryType(CI.getType()), + "cast", &CI); + setLoweredValue(&CI, Cast); + } else { + InstructionLowering lower(&CI, getLength(CI.getOperand(0))); + } } + void LowerVectors::visitGetElementPtrInst(GetElementPtrInst &GEP) { + std::vector idx; + for (User::op_iterator I = GEP.idx_begin(), E = GEP.idx_end(); + I != E; ++I) { + idx.push_back(*I); + } + GetElementPtrInst *NewGEP = + new GetElementPtrInst(getLoweredValue(GEP.getPointerOperand()), + idx, "gep", &GEP); + setLoweredValue(&GEP, NewGEP); + } + void LowerVectors::visitBinaryOperator(BinaryOperator &BO) { Value *op0 = BO.getOperand(0); Value *op1 = BO.getOperand(1); @@ -601,7 +630,12 @@ } void LowerVectors::visitStoreInst(StoreInst &SI) { - if (isa(SI.getOperand(0)->getType())) { + const Type *Ty = SI.getOperand(0)->getType(); + if (const FixedVectorType *VT = dyn_cast(SI.getOperand(0)->getType())) { + Value *length = getLength(SI.getOperand(0));//ConstantUInt::get(Type::UIntTy, VT->getNumElements()); + Value *ptr = getLoweredValue(SI.getOperand(1)); + InstructionLowering lower(&SI, length, ptr); + } else if (isa(SI.getOperand(0)->getType())) { std::vector Idx; Idx.push_back(ConstantUInt::get(Type::UIntTy, 0)); Idx.push_back(ConstantUInt::get(Type::UIntTy, 0)); @@ -623,7 +657,10 @@ } void LowerVectors::visitLoadInst(LoadInst &LI) { - if (isa(cast(LI.getOperand(0)->getType())->getElementType())) { + const Type *Ty = cast(LI.getOperand(0)->getType())->getElementType(); + if (isa(Ty)) { + setLoweredValue(&LI, getLoweredValue(LI.getOperand(0))); + } else if (isa(Ty)) { std::vector Idx; Idx.push_back(ConstantUInt::get(Type::UIntTy, 0)); Idx.push_back(ConstantUInt::get(Type::UIntTy, 1)); @@ -654,7 +691,16 @@ const VectorType *VectorTy = dyn_cast(Ty); assert(VectorTy && "Instruction must be of vector type!"); const Type *elementType = VectorTy->getElementType(); - vector = allocateVector(elementType, length, "vector", I, ptr); + if (isa(Ty)) { + if (isa(I)) { + vector = ptr; + } else { + vector = new AllocaInst(VectorTy->getElementType(), length, "vector", + &(I->getParent()->getParent()->getEntryBlock().front())); + } + } else { + vector = allocateVector(elementType, length, "vector", I, ptr); + } setLoweredValue(I, vector, length); // Set up the loop index @@ -751,7 +797,7 @@ void InstructionLowering::visitCombineInst(CombineInst &CI) { // Here we are generating code for // - // %tmp = extract v1, v2, start, stride + // %tmp = combine v1, v2, start, stride // // First we compute secondIndex, the index into v2. If start <= // vectorIndex < start + stride * getLength(v2), then @@ -1001,7 +1047,7 @@ // VScatterLowering implementation //===----------------------------------------------------------------------===// - /// Lower a vstore instruction. Find the array that holds the + /// Lower a vscatter instruction. Find the array that holds the /// vector contents, then copy that array to the indexed memory /// locations. /// Index: llvm/lib/Transforms/Vector/RaiseVectors.cpp diff -u llvm/lib/Transforms/Vector/RaiseVectors.cpp:1.1.2.1 llvm/lib/Transforms/Vector/RaiseVectors.cpp:1.1.2.2 --- llvm/lib/Transforms/Vector/RaiseVectors.cpp:1.1.2.1 Tue Oct 18 14:37:03 2005 +++ llvm/lib/Transforms/Vector/RaiseVectors.cpp Tue Nov 15 14:15:33 2005 @@ -492,10 +492,13 @@ /// Raise a phi node /// void RaiseVectors::visitPHINode(PHINode &PN) { - PHINode *raisedValue = - new PHINode(VectorType::get(PN.getType()), "phi", - &PN); unsigned length = getVectorLength(&PN); + const VectorType *VT = 0; + if (length) + VT = FixedVectorType::get(PN.getType(), length); + else + VT = VectorType::get(PN.getType()); + PHINode *raisedValue = new PHINode(VT, "phi", &PN); for (unsigned i = 0; i < PN.getNumIncomingValues(); ++i) raisedValue->addIncoming(getRaisedValue(PN.getIncomingValue(i), length), PN.getIncomingBlock(i)); Index: llvm/lib/Transforms/Vector/SSE.cpp diff -u llvm/lib/Transforms/Vector/SSE.cpp:1.1.2.1 llvm/lib/Transforms/Vector/SSE.cpp:1.1.2.2 --- llvm/lib/Transforms/Vector/SSE.cpp:1.1.2.1 Tue Oct 18 14:37:03 2005 +++ llvm/lib/Transforms/Vector/SSE.cpp Tue Nov 15 14:15:33 2005 @@ -43,7 +43,6 @@ bool runOnFunction(Function &F); void visitCastInst(CastInst &); void visitVImmInst(VImmInst &); - void visitExtractInst(ExtractInst &); void visitCombineInst(CombineInst &); void visitVSelectInst(VSelectInst &); void visitAdd(BinaryOperator &); @@ -165,7 +164,6 @@ DEBUG(std::cerr << "Visiting instruction " << *BI); visit(*BI); } - //visit(F); if (changed) deleteInstructions(); return changed; } @@ -204,72 +202,9 @@ changed = true; } } - } else { - // We need to use a _mm_set instruction - // - const Type *Ty = CI.getOperand(0)->getType(); - unsigned primitiveSize = Ty->getPrimitiveSize(); - unsigned vectorSize = getVectorSize(Ty); - const FixedVectorType *RetTy = FixedVectorType::get(Ty, vectorSize); - CallInst *call = VectorUtils::getCallInst(RetTy, getSSEName("splat", RetTy), - CI.getOperand(0), "splat", &CI); - if (RetTy != CI.getType()) - CI.replaceAllUsesWith(new CastInst(call, CI.getType(), "cast", &CI)); - else - CI.replaceAllUsesWith(call); - instructionsToDelete.insert(&CI); - changed = true; } } - // Check whether an extract instruction should be turned into - // SSE_unpack - // - // FIXME: This code doesn't work - // - void SSE::visitExtractInst(ExtractInst &EI) { - Value *v = EI.getOperand(0); - ConstantUInt *start = dyn_cast(EI.getOperand(1)); - ConstantUInt *stride = dyn_cast(EI.getOperand(2)); - ConstantUInt *len = dyn_cast(EI.getOperand(3)); - if (!start || !stride || !len) return; - if (stride->getValue() != 1 || len->getValue() != 8) return; - std::string funcName; - if (start->getValue() == 0) - funcName = "SSE_unpackh_short"; - else if (start->getValue() == 8) - funcName = "SSE_unpackl_short"; - else return; - const FixedVectorType *VT = dyn_cast(v->getType()); - if (VT == FixedVectorType::get(Type::UByteTy, 16)) { - if (!EI.hasOneUse()) return; - CastInst *cast = dyn_cast(*EI.use_begin()); - if (!cast) return; - const FixedVectorType *argTy = FixedVectorType::get(Type::SByteTy, 16); - const FixedVectorType *retTy = FixedVectorType::get(Type::ShortTy, 8); - if (cast->getType() != FixedVectorType::get(Type::ShortTy, 8)) - return; - CastInst *arg = new CastInst(v, argTy, "cast", &EI); - std::vector formalArgs; - formalArgs.push_back(argTy); - std::vector args; - args.push_back(arg); - FunctionType *FType = FunctionType::get(retTy, formalArgs, false); - Module *M = EI.getParent()->getParent()->getParent(); - Function *unpack = - M->getOrInsertFunction(funcName, FType); - CallInst *call = new CallInst(unpack, args, "unpack", &EI); - BinaryOperator *andInst = - BinaryOperator::create(Instruction::And, call, - ConstantExpr::getCast(ConstantSInt::get(Type::ShortTy, 0xFF), retTy), - "and", &EI); - cast->replaceAllUsesWith(andInst); - instructionsToDelete.insert(cast); - instructionsToDelete.insert(&EI); - changed = true; - } - } - void SSE::visitCombineInst(CombineInst &CI) { Instruction *combine1 = cast(&CI); Value *v1 = CI.getOperand(0); From natebegeman at mac.com Tue Nov 15 18:48:20 2005 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 15 Nov 2005 18:48:20 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp PPCCodeEmitter.cpp PPCISelDAGToDAG.cpp PPCISelPattern.cpp PPCInstrInfo.td Message-ID: <200511160048.SAA13999@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.109 -> 1.110 PPCCodeEmitter.cpp updated: 1.40 -> 1.41 PPCISelDAGToDAG.cpp updated: 1.125 -> 1.126 PPCISelPattern.cpp updated: 1.191 -> 1.192 PPCInstrInfo.td updated: 1.138 -> 1.139 --- Log message: Patch to clean up function call pseudos and support the BLA instruction, which branches to an absolute address. This is required to support objc direct dispatch. --- Diffs of the changes: (+31 -20) PPCAsmPrinter.cpp | 4 ++++ PPCCodeEmitter.cpp | 2 +- PPCISelDAGToDAG.cpp | 23 +++++++++++++++++------ PPCISelPattern.cpp | 9 +++------ PPCInstrInfo.td | 13 ++++++------- 5 files changed, 31 insertions(+), 20 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.109 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.110 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.109 Mon Nov 14 19:45:01 2005 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Tue Nov 15 18:48:01 2005 @@ -152,6 +152,10 @@ TM.getInstrInfo()->isCall(MI->getOpcode())); } } + void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo, + MVT::ValueType VT) { + O << (int)MI->getOperand(OpNo).getImmedValue()*4; + } void printPICLabel(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT) { // FIXME: should probably be converted to cout.width and cout.fill Index: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp diff -u llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.40 llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.41 --- llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.40 Sun Oct 16 00:39:50 2005 +++ llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp Tue Nov 15 18:48:01 2005 @@ -196,7 +196,7 @@ MO.getGlobal()->hasWeakLinkage() || MO.getGlobal()->isExternal(); unsigned Reloc = 0; - if (MI.getOpcode() == PPC::CALLpcrel) + if (MI.getOpcode() == PPC::BL) Reloc = PPC::reloc_pcrel_bx; else { switch (MI.getOpcode()) { Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.125 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.126 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.125 Fri Oct 28 17:58:07 2005 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Tue Nov 15 18:48:01 2005 @@ -735,6 +735,14 @@ return SDOperand(N, 0); } +/// isCallCompatibleAddress - Return true if the specified 32-bit value is +/// representable in the immediate field of a Bx instruction. +static bool isCallCompatibleAddress(ConstantSDNode *C) { + int Addr = C->getValue(); + if (Addr & 3) return false; // Low 2 bits are implicitly zero. + return (Addr << 6 >> 6) == Addr; // Top 6 bits have to be sext of immediate. +} + SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) { SDNode *N = Op.Val; SDOperand Chain = Select(N->getOperand(0)); @@ -744,13 +752,18 @@ if (GlobalAddressSDNode *GASD = dyn_cast(N->getOperand(1))) { - CallOpcode = PPC::CALLpcrel; + CallOpcode = PPC::BL; CallOperands.push_back(CurDAG->getTargetGlobalAddress(GASD->getGlobal(), MVT::i32)); } else if (ExternalSymbolSDNode *ESSDN = dyn_cast(N->getOperand(1))) { - CallOpcode = PPC::CALLpcrel; + CallOpcode = PPC::BL; CallOperands.push_back(N->getOperand(1)); + } else if (isa(N->getOperand(1)) && + isCallCompatibleAddress(cast(N->getOperand(1)))) { + ConstantSDNode *C = cast(N->getOperand(1)); + CallOpcode = PPC::BLA; + CallOperands.push_back(getI32Imm((int)C->getValue() >> 2)); } else { // Copy the callee address into the CTR register. SDOperand Callee = Select(N->getOperand(1)); @@ -759,11 +772,9 @@ // Copy the callee address into R12 on darwin. SDOperand R12 = CurDAG->getRegister(PPC::R12, MVT::i32); Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, R12, Callee); - - CallOperands.push_back(getI32Imm(20)); // Information to encode indcall - CallOperands.push_back(getI32Imm(0)); // Information to encode indcall + CallOperands.push_back(R12); - CallOpcode = PPC::CALLindirect; + CallOpcode = PPC::BCTRL; } unsigned GPR_idx = 0, FPR_idx = 0; Index: llvm/lib/Target/PowerPC/PPCISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.191 llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.192 --- llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.191 Wed Oct 19 21:15:44 2005 +++ llvm/lib/Target/PowerPC/PPCISelPattern.cpp Tue Nov 15 18:48:01 2005 @@ -842,18 +842,15 @@ // Emit the correct call instruction based on the type of symbol called. if (GlobalAddressSDNode *GASD = dyn_cast(N.getOperand(1))) { - CallMI = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(), - true); + CallMI = BuildMI(PPC::BL, 1).addGlobalAddress(GASD->getGlobal(), true); } else if (ExternalSymbolSDNode *ESSDN = dyn_cast(N.getOperand(1))) { - CallMI = BuildMI(PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(), - true); + CallMI = BuildMI(PPC::BL, 1).addExternalSymbol(ESSDN->getSymbol(), true); } else { Tmp1 = SelectExpr(N.getOperand(1)); BuildMI(BB, PPC::MTCTR, 1).addReg(Tmp1); BuildMI(BB, PPC::OR4, 2, PPC::R12).addReg(Tmp1).addReg(Tmp1); - CallMI = BuildMI(PPC::CALLindirect, 3).addImm(20).addImm(0) - .addReg(PPC::R12); + CallMI = BuildMI(PPC::BCTRL, 1).addReg(PPC::R12); } // Load the register args to virtual regs Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.138 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.139 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.138 Fri Oct 28 15:32:44 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Tue Nov 15 18:48:01 2005 @@ -128,6 +128,9 @@ def target : Operand { let PrintMethod = "printBranchOperand"; } +def aaddr : Operand { + let PrintMethod = "printAbsAddrOperand"; +} def piclabel: Operand { let PrintMethod = "printPICLabel"; } @@ -186,9 +189,6 @@ target:$true, target:$false), "; COND_BRANCH", []>; def B : IForm<18, 0, 0, (ops target:$func), "b $func", BrB>; -//def BA : IForm<18, 1, 0, (ops target:$func), "ba $func", BrB>; - def BL : IForm<18, 0, 1, (ops target:$func), "bl $func", BrB>; -//def BLA : IForm<18, 1, 1, (ops target:$func), "bla $func", BrB>; // FIXME: 4*CR# needs to be added to the BI field! // This will only work for CR0 as it stands now @@ -217,10 +217,9 @@ LR,CTR, CR0,CR1,CR5,CR6,CR7] in { // Convenient aliases for call instructions - def CALLpcrel : IForm<18, 0, 1, (ops target:$func, variable_ops), - "bl $func", BrB>; - def CALLindirect : XLForm_2_ext<19, 528, 20, 0, 1, - (ops variable_ops), "bctrl", BrB>; + def BL : IForm<18, 0, 1, (ops target:$func, variable_ops), "bl $func", BrB>; + def BLA : IForm<18, 1, 1, (ops aaddr:$func, variable_ops), "bla $func", BrB>; + def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (ops variable_ops), "bctrl", BrB>; } // D-Form instructions. Most instructions that perform an operation on a From lattner at cs.uiuc.edu Tue Nov 15 19:54:44 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 15 Nov 2005 19:54:44 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Makefile X86TargetMachine.cpp Message-ID: <200511160154.TAA14489@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp added (r1.1) Makefile updated: 1.23 -> 1.24 X86TargetMachine.cpp updated: 1.88 -> 1.89 --- Log message: initial step at adding a dag-to-dag isel for X86 backend. Patch contributed by Evan Cheng! --- Diffs of the changes: (+175 -3) Makefile | 2 X86ISelDAGToDAG.cpp | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++ X86TargetMachine.cpp | 13 +++- 3 files changed, 175 insertions(+), 3 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -c /dev/null llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.1 *** /dev/null Tue Nov 15 19:54:42 2005 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Nov 15 19:54:32 2005 *************** *** 0 **** --- 1,163 ---- + //===-- X86ISelPattern.cpp - A DAG pattern matching inst selector for X86 -===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the Evan Cheng and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file defines a DAG pattern matching instruction selector for X86, + // converting from a legalized dag to a X86 dag. + // + //===----------------------------------------------------------------------===// + + #include "X86.h" + #include "X86Subtarget.h" + #include "X86ISelLowering.h" + #include "llvm/CodeGen/MachineFunction.h" + #include "llvm/CodeGen/SelectionDAGISel.h" + #include "llvm/Target/TargetMachine.h" + #include "llvm/Support/Debug.h" + #include "llvm/ADT/Statistic.h" + using namespace llvm; + + //===----------------------------------------------------------------------===// + // Pattern Matcher Implementation + //===----------------------------------------------------------------------===// + + namespace { + Statistic<> + NumFPKill("x86-codegen", "Number of FP_REG_KILL instructions added"); + + //===--------------------------------------------------------------------===// + /// ISel - X86 specific code to select X86 machine instructions for + /// SelectionDAG operations. + /// + class X86DAGToDAGISel : public SelectionDAGISel { + /// ContainsFPCode - Every instruction we select that uses or defines a FP + /// register should set this to true. + bool ContainsFPCode; + + /// X86Lowering - This object fully describes how to lower LLVM code to an + /// X86-specific SelectionDAG. + X86TargetLowering X86Lowering; + + /// Subtarget - Keep a pointer to the X86Subtarget around so that we can + /// make the right decision when generating code for different targets. + const X86Subtarget *Subtarget; + public: + X86DAGToDAGISel(TargetMachine &TM) + : SelectionDAGISel(X86Lowering), X86Lowering(TM) { + Subtarget = &TM.getSubtarget(); + } + + virtual const char *getPassName() const { + return "X86 DAG->DAG Instruction Selection"; + } + + /// InstructionSelectBasicBlock - This callback is invoked by + /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. + virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); + + // Include the pieces autogenerated from the target description. + #include "X86GenDAGISel.inc" + + private: + SDOperand Select(SDOperand N); + + /// getI16Imm - Return a target constant with the specified value, of type + /// i16. + inline SDOperand getI16Imm(unsigned Imm) { + return CurDAG->getTargetConstant(Imm, MVT::i16); + } + + /// getI32Imm - Return a target constant with the specified value, of type + /// i32. + inline SDOperand getI32Imm(unsigned Imm) { + return CurDAG->getTargetConstant(Imm, MVT::i32); + } + }; + } + + /// InstructionSelectBasicBlock - This callback is invoked by SelectionDAGISel + /// when it has created a SelectionDAG for us to codegen. + void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { + DEBUG(BB->dump()); + + // Codegen the basic block. + DAG.setRoot(Select(DAG.getRoot())); + DAG.RemoveDeadNodes(); + + // Emit machine code to BB. + ScheduleAndEmitDAG(DAG); + } + + SDOperand X86DAGToDAGISel::Select(SDOperand Op) { + SDNode *N = Op.Val; + MVT::ValueType OpVT = Op.getValueType(); + unsigned Opc; + + if (N->getOpcode() >= ISD::BUILTIN_OP_END) + return Op; // Already selected. + + switch (N->getOpcode()) { + default: break; + case ISD::Constant: { + switch (OpVT) { + default: assert(0 && "Cannot use constants of this type!"); + case MVT::i1: + case MVT::i8: Opc = X86::MOV8ri; break; + case MVT::i16: Opc = X86::MOV16ri; break; + case MVT::i32: Opc = X86::MOV32ri; break; + } + unsigned CVal = cast(N)->getValue(); + SDOperand Op1 = CurDAG->getTargetConstant(CVal, OpVT); + CurDAG->SelectNodeTo(N, Opc, OpVT, Op1); + return Op; + } + + case ISD::RET: { + SDOperand Chain = Select(N->getOperand(0)); // Token chain. + switch (N->getNumOperands()) { + default: + assert(0 && "Unknown return instruction!"); + case 3: + assert(0 && "Not yet handled return instruction!"); + break; + case 2: { + SDOperand Val = Select(N->getOperand(1)); + switch (N->getOperand(1).getValueType()) { + default: + assert(0 && "All other types should have been promoted!!"); + case MVT::i32: + Chain = CurDAG->getCopyToReg(Chain, X86::EAX, Val); + break; + case MVT::f32: + case MVT::f64: + assert(0 && "Not yet handled return instruction!"); + break; + } + } + case 1: + break; + } + if (X86Lowering.getBytesToPopOnReturn() == 0) + CurDAG->SelectNodeTo(N, X86::RET, MVT::Other, Chain); + else + CurDAG->SelectNodeTo(N, X86::RET, MVT::Other, Chain, + getI16Imm(X86Lowering.getBytesToPopOnReturn())); + + return SDOperand(N, 0); + } + } + + return SelectCode(Op); + } + + /// createX86ISelDag - This pass converts a legalized DAG into a + /// X86-specific DAG, ready for instruction scheduling. + /// + FunctionPass *llvm::createX86ISelDag(TargetMachine &TM) { + return new X86DAGToDAGISel(TM); + } Index: llvm/lib/Target/X86/Makefile diff -u llvm/lib/Target/X86/Makefile:1.23 llvm/lib/Target/X86/Makefile:1.24 --- llvm/lib/Target/X86/Makefile:1.23 Thu Dec 16 11:33:24 2004 +++ llvm/lib/Target/X86/Makefile Tue Nov 15 19:54:32 2005 @@ -13,7 +13,7 @@ BUILT_SOURCES = X86GenRegisterInfo.h.inc X86GenRegisterNames.inc \ X86GenRegisterInfo.inc X86GenInstrNames.inc \ X86GenInstrInfo.inc X86GenAsmWriter.inc \ - X86GenAsmWriter1.inc + X86GenAsmWriter1.inc X86GenDAGISel.inc include $(LEVEL)/Makefile.common Index: llvm/lib/Target/X86/X86TargetMachine.cpp diff -u llvm/lib/Target/X86/X86TargetMachine.cpp:1.88 llvm/lib/Target/X86/X86TargetMachine.cpp:1.89 --- llvm/lib/Target/X86/X86TargetMachine.cpp:1.88 Mon Nov 14 18:40:24 2005 +++ llvm/lib/Target/X86/X86TargetMachine.cpp Tue Nov 15 19:54:32 2005 @@ -47,6 +47,9 @@ cl::location(X86ScalarSSE), cl::init(false)); + cl::opt EnableX86DAGDAG("enable-x86-dag-isel", cl::Hidden, + cl::desc("Enable DAG-to-DAG isel for X86")); + // FIXME: This should eventually be handled with target triples and // subtarget support! cl::opt @@ -124,7 +127,10 @@ PM.add(createUnreachableBlockEliminationPass()); // Install an instruction selector. - PM.add(createX86ISelPattern(*this)); + if (EnableX86DAGDAG) + PM.add(createX86ISelDag(*this)); + else + PM.add(createX86ISelPattern(*this)); // Run optional SSA-based machine code optimizations next... if (!NoSSAPeephole) @@ -192,7 +198,10 @@ PM.add(createUnreachableBlockEliminationPass()); // Install an instruction selector. - PM.add(createX86ISelPattern(TM)); + if (EnableX86DAGDAG) + PM.add(createX86ISelDag(TM)); + else + PM.add(createX86ISelPattern(TM)); // Run optional SSA-based machine code optimizations next... if (!NoSSAPeephole) From lattner at cs.uiuc.edu Wed Nov 16 00:09:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 16 Nov 2005 00:09:59 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Type.cpp Message-ID: <200511160609.AAA20399@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Type.cpp updated: 1.136 -> 1.137 --- Log message: * Fix DerivedType::dropAllTypeUses to not change the number of types in a type when it gets refined. This allows us to hash on this crucial value. * Fix several issues in TypeMap::RefineAbstractType that prevent it from handling hash values that change correctly. * Define hashTypeStructure to not always return 0. :) This last part (which depends on the first two) speeds up gccld time on eon from 3.78s to 2.75s with a release build (a 28% speedup!). This resolves PR474: http://llvm.cs.uiuc.edu/PR474 . --- Diffs of the changes: (+65 -22) Type.cpp | 87 +++++++++++++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 65 insertions(+), 22 deletions(-) Index: llvm/lib/VMCore/Type.cpp diff -u llvm/lib/VMCore/Type.cpp:1.136 llvm/lib/VMCore/Type.cpp:1.137 --- llvm/lib/VMCore/Type.cpp:1.136 Sat Nov 12 21:26:33 2005 +++ llvm/lib/VMCore/Type.cpp Wed Nov 16 00:09:47 2005 @@ -471,14 +471,17 @@ // types, to avoid some circular reference problems. void DerivedType::dropAllTypeUses() { if (!ContainedTys.empty()) { - while (ContainedTys.size() > 1) - ContainedTys.pop_back(); - // The type must stay abstract. To do this, we insert a pointer to a type // that will never get resolved, thus will always be abstract. static Type *AlwaysOpaqueTy = OpaqueType::get(); static PATypeHolder Holder(AlwaysOpaqueTy); ContainedTys[0] = AlwaysOpaqueTy; + + // Change the rest of the types to be intty's. It doesn't matter what we + // pick so long as it doesn't point back to this type. We choose something + // concrete to avoid overhead for adding to AbstracTypeUser lists and stuff. + for (unsigned i = 1, e = ContainedTys.size(); i != e; ++i) + ContainedTys[i] = Type::IntTy; } } @@ -680,6 +683,37 @@ return false; } +/// getSubElementHash - Generate a hash value for all of the SubType's of this +/// type. The hash value is guaranteed to be zero if any of the subtypes are +/// an opaque type. Otherwise we try to mix them in as well as possible, but do +/// not look at the subtype's subtype's. +static unsigned getSubElementHash(const Type *Ty) { + unsigned HashVal = 0; + for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); + I != E; ++I) { + HashVal *= 32; + const Type *SubTy = I->get(); + HashVal += SubTy->getTypeID(); + switch (SubTy->getTypeID()) { + default: break; + case Type::OpaqueTyID: return 0; // Opaque -> hash = 0 no matter what. + case Type::FunctionTyID: + HashVal ^= cast(SubTy)->getNumParams()*2 + + cast(SubTy)->isVarArg(); + break; + case Type::ArrayTyID: + HashVal ^= cast(SubTy)->getNumElements(); + break; + case Type::PackedTyID: + HashVal ^= cast(SubTy)->getNumElements(); + break; + case Type::StructTyID: + HashVal ^= cast(SubTy)->getNumElements(); + break; + } + } + return HashVal ? HashVal : 1; // Do not return zero unless opaque subty. +} //===----------------------------------------------------------------------===// // Derived Type Factory Functions @@ -697,12 +731,18 @@ public: void RemoveFromTypesByHash(unsigned Hash, const Type *Ty) { std::multimap::iterator I = - TypesByHash.lower_bound(Hash); - while (I->second != Ty) { - ++I; - assert(I != TypesByHash.end() && I->first == Hash); + TypesByHash.lower_bound(Hash); + for (; I != TypesByHash.end() && I->first == Hash; ++I) { + if (I->second == Ty) { + TypesByHash.erase(I); + return; + } } - TypesByHash.erase(I); + + // This must be do to an opaque type that was resolved. Switch down to hash + // code of zero. + assert(Hash && "Didn't find type entry!"); + RemoveFromTypesByHash(0, Ty); } /// TypeBecameConcrete - When Ty gets a notification that TheType just became @@ -803,7 +843,6 @@ tie(I, Inserted) = Map.insert(std::make_pair(ValType::get(Ty), Ty)); if (!Inserted) { - assert(OldType != NewType); // Refined to a different type altogether? RemoveFromTypesByHash(OldTypeHash, Ty); @@ -819,7 +858,7 @@ // gets refined to the pre-existing type. // std::multimap::iterator I, E, Entry; - tie(I, E) = TypesByHash.equal_range(OldTypeHash); + tie(I, E) = TypesByHash.equal_range(NewTypeHash); Entry = E; for (; I != E; ++I) { if (I->second == Ty) { @@ -829,16 +868,23 @@ if (TypesEqual(Ty, I->second)) { TypeClass *NewTy = cast((Type*)I->second.get()); - if (Entry == E) { - // Find the location of Ty in the TypesByHash structure if we - // haven't seen it already. - while (I->second != Ty) { - ++I; - assert(I != E && "Structure doesn't contain type??"); + // Remove the old entry form TypesByHash. If the hash values differ + // now, remove it from the old place. Otherwise, continue scanning + // withing this hashcode to reduce work. + if (NewTypeHash != OldTypeHash) { + RemoveFromTypesByHash(OldTypeHash, Ty); + } else { + if (Entry == E) { + // Find the location of Ty in the TypesByHash structure if we + // haven't seen it already. + while (I->second != Ty) { + ++I; + assert(I != E && "Structure doesn't contain type??"); + } + Entry = I; } - Entry = I; + TypesByHash.erase(Entry); } - TypesByHash.erase(Entry); Ty->refineAbstractTypeTo(NewTy); return; } @@ -1122,7 +1168,7 @@ } static unsigned hashTypeStructure(const PointerType *PT) { - return 0; + return getSubElementHash(PT); } // Subclass should override this... to update self as usual @@ -1284,9 +1330,6 @@ } } - - - // refineAbstractType - Called when a contained type is found to be more // concrete - this could potentially change us from an abstract type to a // concrete type. From jeffc at jolt-lang.org Wed Nov 16 00:11:05 2005 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Wed, 16 Nov 2005 00:11:05 -0600 Subject: [llvm-commits] CVS: llvm/win32/x86/x86.vcproj Message-ID: <200511160611.AAA20445@zion.cs.uiuc.edu> Changes in directory llvm/win32/x86: x86.vcproj updated: 1.15 -> 1.16 --- Log message: Keep Visual Studio building. --- Diffs of the changes: (+10 -4) x86.vcproj | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-) Index: llvm/win32/x86/x86.vcproj diff -u llvm/win32/x86/x86.vcproj:1.15 llvm/win32/x86/x86.vcproj:1.16 --- llvm/win32/x86/x86.vcproj:1.15 Tue Nov 15 10:11:55 2005 +++ llvm/win32/x86/x86.vcproj Wed Nov 16 00:10:53 2005 @@ -121,9 +121,9 @@ ..\$(IntDir)\TableGen.exe -gen-instr-desc -I ..\..\lib\Target\X86 $(InputPath) -o X86GenInstrInfo.inc ..\$(IntDir)\TableGen.exe -gen-asm-writer -I ..\..\lib\Target\X86 $(InputPath) -o X86GenAsmWriter.inc ..\$(IntDir)\TableGen.exe -gen-asm-writer -asmwriternum=1 -I ..\..\lib\Target\X86 $(InputPath) -o X86GenAsmWriter1.inc -" +..\$(IntDir)\TableGen.exe -gen-dag-isel -I ..\..\lib\Target\X86 $(InputPath) -o X86GenDAGISel.inc" AdditionalDependencies="$(InputDir)X86InstrInfo.td;$(InputDir)X86RegisterInfo.td;$(InputDir)..\Target.td;$(ProjectDir)..\$(IntDir)\TableGen.exe" - Outputs="X86GenRegisterNames.inc;X86GenRegisterInfo.h.inc;X86GenRegisterInfo.inc;X86GenInstrNames.inc;X86GenInstrInfo.inc;X86GenAsmWriter.inc;X86GenAsmWriter1.inc"/> + Outputs="X86GenRegisterNames.inc;X86GenRegisterInfo.h.inc;X86GenRegisterInfo.inc;X86GenInstrNames.inc;X86GenInstrInfo.inc;X86GenAsmWriter.inc;X86GenAsmWriter1.inc;X86GenDAGISel.inc"/> @@ -137,9 +137,9 @@ ..\$(IntDir)\TableGen.exe -gen-instr-desc -I ..\..\lib\Target\X86 $(InputPath) -o X86GenInstrInfo.inc ..\$(IntDir)\TableGen.exe -gen-asm-writer -I ..\..\lib\Target\X86 $(InputPath) -o X86GenAsmWriter.inc ..\$(IntDir)\TableGen.exe -gen-asm-writer -asmwriternum=1 -I ..\..\lib\Target\X86 $(InputPath) -o X86GenAsmWriter1.inc -" +..\$(IntDir)\TableGen.exe -gen-dag-isel -I ..\..\lib\Target\X86 $(InputPath) -o X86GenDAGISel.inc" AdditionalDependencies="$(InputDir)X86InstrInfo.td;$(InputDir)X86RegisterInfo.td;$(InputDir)..\Target.td;$(ProjectDir)..\$(IntDir)\TableGen.exe" - Outputs="X86GenRegisterNames.inc;X86GenRegisterInfo.h.inc;X86GenRegisterInfo.inc;X86GenInstrNames.inc;X86GenInstrInfo.inc;X86GenAsmWriter.inc;X86GenAsmWriter1.inc"/> + Outputs="X86GenRegisterNames.inc;X86GenRegisterInfo.h.inc;X86GenRegisterInfo.inc;X86GenInstrNames.inc;X86GenInstrInfo.inc;X86GenAsmWriter.inc;X86GenAsmWriter1.inc;X86GenDAGISel.inc"/> + + + + Changes in directory llvm/lib/Support: CommandLine.cpp updated: 1.63 -> 1.64 --- Log message: indicate when a tool is a debug build. --- Diffs of the changes: (+6 -1) CommandLine.cpp | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletion(-) Index: llvm/lib/Support/CommandLine.cpp diff -u llvm/lib/Support/CommandLine.cpp:1.63 llvm/lib/Support/CommandLine.cpp:1.64 --- llvm/lib/Support/CommandLine.cpp:1.63 Mon Aug 8 16:57:27 2005 +++ llvm/lib/Support/CommandLine.cpp Wed Nov 16 00:36:47 2005 @@ -941,7 +941,12 @@ void operator=(bool OptionWasSpecified) { if (OptionWasSpecified) { std::cerr << "Low Level Virtual Machine (" << PACKAGE_NAME << ") " - << PACKAGE_VERSION << " (see http://llvm.cs.uiuc.edu/)\n"; + << PACKAGE_VERSION << " (see http://llvm.org/)"; +#ifndef NDEBUG + std::cerr << " DEBUG BUILD\n"; +#else + std::cerr << "\n"; +#endif getOpts().clear(); // Don't bother making option dtors remove from map. exit(1); } From lattner at cs.uiuc.edu Wed Nov 16 01:21:26 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 16 Nov 2005 01:21:26 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/IntrinsicLowering.h Message-ID: <200511160721.BAA20882@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: IntrinsicLowering.h updated: 1.8 -> 1.9 --- Log message: add a flag --- Diffs of the changes: (+5 -0) IntrinsicLowering.h | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/include/llvm/CodeGen/IntrinsicLowering.h diff -u llvm/include/llvm/CodeGen/IntrinsicLowering.h:1.8 llvm/include/llvm/CodeGen/IntrinsicLowering.h:1.9 --- llvm/include/llvm/CodeGen/IntrinsicLowering.h:1.8 Thu Apr 21 15:38:00 2005 +++ llvm/include/llvm/CodeGen/IntrinsicLowering.h Wed Nov 16 01:21:15 2005 @@ -40,9 +40,14 @@ class Module; class IntrinsicLowering { + protected: + bool ShouldEmitDebugFunctions; public: + IntrinsicLowering() : ShouldEmitDebugFunctions(false) {} virtual ~IntrinsicLowering() {} + bool EmitDebugFunctions() const { return ShouldEmitDebugFunctions; } + /// AddPrototypes - This method, if called, causes all of the prototypes /// that might be needed by an intrinsic lowering implementation to be /// inserted into the module specified. From lattner at cs.uiuc.edu Wed Nov 16 01:21:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 16 Nov 2005 01:21:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Debugger/UnixLocalInferiorProcess.cpp Message-ID: <200511160721.BAA20942@zion.cs.uiuc.edu> Changes in directory llvm/lib/Debugger: UnixLocalInferiorProcess.cpp updated: 1.9 -> 1.10 --- Log message: tell selectiondag when we're debugging --- Diffs of the changes: (+1 -0) UnixLocalInferiorProcess.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Debugger/UnixLocalInferiorProcess.cpp diff -u llvm/lib/Debugger/UnixLocalInferiorProcess.cpp:1.9 llvm/lib/Debugger/UnixLocalInferiorProcess.cpp:1.10 --- llvm/lib/Debugger/UnixLocalInferiorProcess.cpp:1.9 Sat Oct 22 23:37:20 2005 +++ llvm/lib/Debugger/UnixLocalInferiorProcess.cpp Wed Nov 16 01:21:47 2005 @@ -861,6 +861,7 @@ /// lowering class that revectors debugging intrinsics to call actual /// functions (defined above), instead of being turned into noops. struct DebuggerIntrinsicLowering : public DefaultIntrinsicLowering { + DebuggerIntrinsicLowering() { ShouldEmitDebugFunctions = true; } virtual void LowerIntrinsicCall(CallInst *CI) { Module *M = CI->getParent()->getParent()->getParent(); switch (CI->getCalledFunction()->getIntrinsicID()) { From lattner at cs.uiuc.edu Wed Nov 16 01:22:42 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 16 Nov 2005 01:22:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200511160722.BAA20999@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.99 -> 1.100 --- Log message: when debugging lower dbg intrinsics to calls --- Diffs of the changes: (+22 -0) SelectionDAGISel.cpp | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.99 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.100 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.99 Fri Nov 11 16:48:54 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Nov 16 01:22:30 2005 @@ -19,6 +19,7 @@ #include "llvm/Function.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" +#include "llvm/CodeGen/IntrinsicLowering.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" @@ -780,10 +781,31 @@ getRoot(), getValue(I.getOperand(1)), getValue(I.getOperand(2)))); return 0; + case Intrinsic::dbg_stoppoint: + if (TLI.getTargetMachine().getIntrinsicLowering().EmitDebugFunctions()) + return "llvm_debugger_stop"; + if (I.getType() != Type::VoidTy) + setValue(&I, DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType()))); + return 0; case Intrinsic::dbg_region_start: + if (TLI.getTargetMachine().getIntrinsicLowering().EmitDebugFunctions()) + return "llvm_dbg_region_start"; + if (I.getType() != Type::VoidTy) + setValue(&I, DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType()))); + return 0; case Intrinsic::dbg_region_end: + if (TLI.getTargetMachine().getIntrinsicLowering().EmitDebugFunctions()) + return "llvm_dbg_region_end"; + if (I.getType() != Type::VoidTy) + setValue(&I, DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType()))); + return 0; case Intrinsic::dbg_func_start: + if (TLI.getTargetMachine().getIntrinsicLowering().EmitDebugFunctions()) + return "llvm_dbg_subprogram"; + if (I.getType() != Type::VoidTy) + setValue(&I, DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType()))); + return 0; case Intrinsic::dbg_declare: if (I.getType() != Type::VoidTy) setValue(&I, DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType()))); From lattner at cs.uiuc.edu Wed Nov 16 01:24:42 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 16 Nov 2005 01:24:42 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Debugger/funccall.ll Message-ID: <200511160724.BAA21034@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Debugger: funccall.ll updated: 1.13 -> 1.14 --- Log message: This passes on ppc and x86 now --- Diffs of the changes: (+1 -1) funccall.ll | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/test/Regression/Debugger/funccall.ll diff -u llvm/test/Regression/Debugger/funccall.ll:1.13 llvm/test/Regression/Debugger/funccall.ll:1.14 --- llvm/test/Regression/Debugger/funccall.ll:1.13 Fri May 13 21:33:20 2005 +++ llvm/test/Regression/Debugger/funccall.ll Wed Nov 16 01:24:31 2005 @@ -8,7 +8,7 @@ ;; RUN: llvm-as -f %s -o %t.bc ;; RUN: llvm-db %t.bc < %t.commands | grep 'in main at funccall.c:11:2' -; XFAIL: i.86|powerpc|alpha|ia64 +; XFAIL: alpha|ia64 ;; Debugger type declarations %lldb.compile_unit = type { uint, ushort, ushort, sbyte*, sbyte*, sbyte*, {}* } From bocchino at cs.uiuc.edu Wed Nov 16 12:31:04 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:31:04 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/Makefile.rules configure Message-ID: <200511161831.MAA20527@zion.cs.uiuc.edu> Changes in directory llvm: Makefile.rules updated: 1.327 -> 1.327.2.1 configure updated: 1.198 -> 1.198.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+181 -18) Makefile.rules | 22 +++++-- configure | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 181 insertions(+), 18 deletions(-) Index: llvm/Makefile.rules diff -u llvm/Makefile.rules:1.327 llvm/Makefile.rules:1.327.2.1 --- llvm/Makefile.rules:1.327 Fri Oct 14 01:31:58 2005 +++ llvm/Makefile.rules Wed Nov 16 12:30:52 2005 @@ -588,9 +588,9 @@ # What the Sparc JIT requires ifdef ENABLE_SPARCV9_JIT JIT_LIBS += LLVMSparcV9 LLVMSparcV9ModuloSched LLVMSparcV9InstrSched \ - LLVMSparcV9LiveVar LLVMInstrumentation.a LLVMProfilePaths \ + LLVMSparcV9LiveVar LLVMInstrumentation.a \ LLVMBCWriter LLVMTransforms.a LLVMipo.a LLVMipa.a \ - LLVMDataStructure.a LLVMSparcV9RegAlloc + LLVMDataStructure LLVMSparcV9RegAlloc endif # You can enable the PowerPC JIT on a non-PowerPC host by setting the flag @@ -617,7 +617,7 @@ JIT_LIBS += LLVMAlpha LLVMSelectionDAG endif -LLVMLIBS := $(JIT_LIBS) LLVMScalarOpts LLVMAnalysis.a LLVMTransformUtils.a \ +LLVMLIBS := $(JIT_LIBS) LLVMScalarOpts.a LLVMTransformUtils.a LLVMAnalysis.a \ LLVMBCReader LLVMCore LLVMSupport.a LLVMTarget.a LLVMbzip2 \ LLVMSystem.a $(PLATFORMLIBDL) endif @@ -824,10 +824,18 @@ #--------------------------------------------------------- # ReLinked Library Targets: -# If the user didn't explicitly forbid building a -# relinked then we provide targets for building them. +# If the user explicitly requests a relinked library with +# BUILD_RELINKED, provide it. Otherwise, if they specify +# neither of BUILD_ARCHIVE or DONT_BUILD_RELINKED, give +# them one. #--------------------------------------------------------- +ifndef BUILD_ARCHIVE ifndef DONT_BUILD_RELINKED +BUILD_RELINKED = 1 +endif +endif + +ifdef BUILD_RELINKED all-local:: $(LibName.O) @@ -1162,6 +1170,10 @@ $(Echo) "Building $(. # @@ -8,7 +8,7 @@ # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # -# $LLVM_COPYRIGHT +# Copyright (c) 2003-2005 University of Illinois at Urbana-Champaign. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## @@ -425,8 +425,8 @@ # Identity of this package. PACKAGE_NAME='llvm' PACKAGE_TARNAME='-llvm-' -PACKAGE_VERSION='1.6cvs' -PACKAGE_STRING='llvm 1.6cvs' +PACKAGE_VERSION='1.7cvs' +PACKAGE_STRING='llvm 1.7cvs' PACKAGE_BUGREPORT='llvmbugs at cs.uiuc.edu' ac_unique_file="lib/VMCore/Module.cpp" @@ -964,7 +964,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures llvm 1.6cvs to adapt to many kinds of systems. +\`configure' configures llvm 1.7cvs to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1026,7 +1026,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of llvm 1.6cvs:";; + short | recursive ) echo "Configuration of llvm 1.7cvs:";; esac cat <<\_ACEOF @@ -1173,14 +1173,14 @@ test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -llvm configure 1.6cvs +llvm configure 1.7cvs generated by GNU Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. -$LLVM_COPYRIGHT +Copyright (c) 2003-2005 University of Illinois at Urbana-Champaign. _ACEOF exit 0 fi @@ -1189,7 +1189,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by llvm $as_me 1.6cvs, which was +It was created by llvm $as_me 1.7cvs, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ @@ -5169,7 +5169,7 @@ echo "${ECHO_T}no" >&6 fi -if test "$GRAPHVIZ" != "echo gv" ; then +if test "$GV" != "echo gv" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_GV 1 @@ -26802,6 +26802,156 @@ done +for ac_header in malloc/malloc.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ----------------------------------- ## +## Report this to llvmbugs at cs.uiuc.edu ## +## ----------------------------------- ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + for ac_header in rw/stdex/hash_map.h rw/stdex/hash_set.h do @@ -27897,7 +28047,8 @@ -for ac_func in strtoll strtoq sysconf + +for ac_func in strtoll strtoq sysconf malloc_zone_statistics do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 @@ -31044,7 +31195,7 @@ } >&5 cat >&5 <<_CSEOF -This file was extended by llvm $as_me 1.6cvs, which was +This file was extended by llvm $as_me 1.7cvs, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -31107,7 +31258,7 @@ cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -llvm config.status 1.6cvs +llvm config.status 1.7cvs configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" From bocchino at cs.uiuc.edu Wed Nov 16 12:31:13 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:31:13 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/Xcode/LLVM.xcodeproj/project.pbxproj Message-ID: <200511161831.MAA20552@zion.cs.uiuc.edu> Changes in directory llvm/Xcode/LLVM.xcodeproj: project.pbxproj updated: 1.10 -> 1.10.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+72 -112) project.pbxproj | 184 +++++++++++++++++++++----------------------------------- 1 files changed, 72 insertions(+), 112 deletions(-) Index: llvm/Xcode/LLVM.xcodeproj/project.pbxproj diff -u llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.10 llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.10.2.1 --- llvm/Xcode/LLVM.xcodeproj/project.pbxproj:1.10 Fri Sep 9 12:50:20 2005 +++ llvm/Xcode/LLVM.xcodeproj/project.pbxproj Wed Nov 16 12:31:02 2005 @@ -80,6 +80,42 @@ /* Begin PBXFileReference section */ CF9BCD0808C74DE0001E7011 /* SubtargetFeature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubtargetFeature.h; sourceTree = ""; }; CF9BCD1508C75070001E7011 /* SubtargetFeature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SubtargetFeature.cpp; sourceTree = ""; }; + DE4DA0390911476D0012D44B /* LoopSimplify.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = LoopSimplify.cpp; path = ../lib/Transforms/Utils/LoopSimplify.cpp; sourceTree = SOURCE_ROOT; }; + DE4DA03C091147920012D44B /* LiveInterval.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = LiveInterval.h; path = ../include/llvm/CodeGen/LiveInterval.h; sourceTree = SOURCE_ROOT; }; + DE4DA03D091147920012D44B /* LiveIntervalAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = LiveIntervalAnalysis.h; path = ../include/llvm/CodeGen/LiveIntervalAnalysis.h; sourceTree = SOURCE_ROOT; }; + DE4DA03E091147C00012D44B /* PrintSCC.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PrintSCC.cpp; path = ../tools/analyze/PrintSCC.cpp; sourceTree = SOURCE_ROOT; }; + DE4DA03F091147DD0012D44B /* PPC.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PPC.h; path = ../lib/Target/PowerPC/PPC.h; sourceTree = SOURCE_ROOT; }; + DE4DA040091147DD0012D44B /* PPC.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = PPC.td; path = ../lib/Target/PowerPC/PPC.td; sourceTree = SOURCE_ROOT; }; + DE4DA041091147DD0012D44B /* PPCAsmPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PPCAsmPrinter.cpp; path = ../lib/Target/PowerPC/PPCAsmPrinter.cpp; sourceTree = SOURCE_ROOT; }; + DE4DA042091147DD0012D44B /* PPCBranchSelector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PPCBranchSelector.cpp; path = ../lib/Target/PowerPC/PPCBranchSelector.cpp; sourceTree = SOURCE_ROOT; }; + DE4DA043091147DD0012D44B /* PPCCodeEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PPCCodeEmitter.cpp; path = ../lib/Target/PowerPC/PPCCodeEmitter.cpp; sourceTree = SOURCE_ROOT; }; + DE4DA044091147DD0012D44B /* PPCFrameInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PPCFrameInfo.h; path = ../lib/Target/PowerPC/PPCFrameInfo.h; sourceTree = SOURCE_ROOT; }; + DE4DA045091147ED0012D44B /* PPCInstrBuilder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PPCInstrBuilder.h; path = ../lib/Target/PowerPC/PPCInstrBuilder.h; sourceTree = SOURCE_ROOT; }; + DE4DA046091147ED0012D44B /* PPCInstrFormats.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = PPCInstrFormats.td; path = ../lib/Target/PowerPC/PPCInstrFormats.td; sourceTree = SOURCE_ROOT; }; + DE4DA047091147ED0012D44B /* PPCInstrInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PPCInstrInfo.cpp; path = ../lib/Target/PowerPC/PPCInstrInfo.cpp; sourceTree = SOURCE_ROOT; }; + DE4DA048091147ED0012D44B /* PPCInstrInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PPCInstrInfo.h; path = ../lib/Target/PowerPC/PPCInstrInfo.h; sourceTree = SOURCE_ROOT; }; + DE4DA049091147ED0012D44B /* PPCInstrInfo.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = PPCInstrInfo.td; path = ../lib/Target/PowerPC/PPCInstrInfo.td; sourceTree = SOURCE_ROOT; }; + DE4DA04A091147ED0012D44B /* PPCISelDAGToDAG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PPCISelDAGToDAG.cpp; path = ../lib/Target/PowerPC/PPCISelDAGToDAG.cpp; sourceTree = SOURCE_ROOT; }; + DE4DA04B091147ED0012D44B /* PPCISelLowering.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PPCISelLowering.cpp; path = ../lib/Target/PowerPC/PPCISelLowering.cpp; sourceTree = SOURCE_ROOT; }; + DE4DA04C091147ED0012D44B /* PPCISelLowering.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PPCISelLowering.h; path = ../lib/Target/PowerPC/PPCISelLowering.h; sourceTree = SOURCE_ROOT; }; + DE4DA04D091147ED0012D44B /* PPCISelPattern.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PPCISelPattern.cpp; path = ../lib/Target/PowerPC/PPCISelPattern.cpp; sourceTree = SOURCE_ROOT; }; + DE4DA04E091147ED0012D44B /* PPCJITInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PPCJITInfo.cpp; path = ../lib/Target/PowerPC/PPCJITInfo.cpp; sourceTree = SOURCE_ROOT; }; + DE4DA04F091147ED0012D44B /* PPCJITInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PPCJITInfo.h; path = ../lib/Target/PowerPC/PPCJITInfo.h; sourceTree = SOURCE_ROOT; }; + DE4DA050091147ED0012D44B /* PPCRegisterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PPCRegisterInfo.cpp; path = ../lib/Target/PowerPC/PPCRegisterInfo.cpp; sourceTree = SOURCE_ROOT; }; + DE4DA051091147ED0012D44B /* PPCRegisterInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PPCRegisterInfo.h; path = ../lib/Target/PowerPC/PPCRegisterInfo.h; sourceTree = SOURCE_ROOT; }; + DE4DA052091147ED0012D44B /* PPCRegisterInfo.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = PPCRegisterInfo.td; path = ../lib/Target/PowerPC/PPCRegisterInfo.td; sourceTree = SOURCE_ROOT; }; + DE4DA053091147ED0012D44B /* PPCRelocations.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PPCRelocations.h; path = ../lib/Target/PowerPC/PPCRelocations.h; sourceTree = SOURCE_ROOT; }; + DE4DA054091147ED0012D44B /* PPCSchedule.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = PPCSchedule.td; path = ../lib/Target/PowerPC/PPCSchedule.td; sourceTree = SOURCE_ROOT; }; + DE4DA055091147ED0012D44B /* PPCScheduleG3.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = PPCScheduleG3.td; path = ../lib/Target/PowerPC/PPCScheduleG3.td; sourceTree = SOURCE_ROOT; }; + DE4DA056091147ED0012D44B /* PPCScheduleG4.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = PPCScheduleG4.td; path = ../lib/Target/PowerPC/PPCScheduleG4.td; sourceTree = SOURCE_ROOT; }; + DE4DA057091147ED0012D44B /* PPCScheduleG4Plus.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = PPCScheduleG4Plus.td; path = ../lib/Target/PowerPC/PPCScheduleG4Plus.td; sourceTree = SOURCE_ROOT; }; + DE4DA058091147ED0012D44B /* PPCScheduleG5.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = PPCScheduleG5.td; path = ../lib/Target/PowerPC/PPCScheduleG5.td; sourceTree = SOURCE_ROOT; }; + DE4DA059091147ED0012D44B /* PPCSubtarget.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PPCSubtarget.cpp; path = ../lib/Target/PowerPC/PPCSubtarget.cpp; sourceTree = SOURCE_ROOT; }; + DE4DA05A091147ED0012D44B /* PPCSubtarget.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PPCSubtarget.h; path = ../lib/Target/PowerPC/PPCSubtarget.h; sourceTree = SOURCE_ROOT; }; + DE4DA05B091147ED0012D44B /* PPCTargetMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PPCTargetMachine.cpp; path = ../lib/Target/PowerPC/PPCTargetMachine.cpp; sourceTree = SOURCE_ROOT; }; + DE4DA05C091147ED0012D44B /* PPCTargetMachine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PPCTargetMachine.h; path = ../lib/Target/PowerPC/PPCTargetMachine.h; sourceTree = SOURCE_ROOT; }; + DE4DA065091148520012D44B /* SubtargetEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SubtargetEmitter.cpp; path = ../utils/TableGen/SubtargetEmitter.cpp; sourceTree = SOURCE_ROOT; }; + DE4DA066091148520012D44B /* SubtargetEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SubtargetEmitter.h; path = ../utils/TableGen/SubtargetEmitter.h; sourceTree = SOURCE_ROOT; }; DE66EC5B08ABE86900323D32 /* AsmWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AsmWriter.cpp; path = ../lib/VMCore/AsmWriter.cpp; sourceTree = SOURCE_ROOT; }; DE66EC5C08ABE86A00323D32 /* BasicBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = BasicBlock.cpp; path = ../lib/VMCore/BasicBlock.cpp; sourceTree = SOURCE_ROOT; }; DE66EC5D08ABE86A00323D32 /* ConstantFolding.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ConstantFolding.cpp; path = ../lib/VMCore/ConstantFolding.cpp; sourceTree = SOURCE_ROOT; }; @@ -137,17 +173,14 @@ DE66ECE908ABEC0700323D32 /* Printer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Printer.cpp; sourceTree = ""; }; DE66ECEA08ABEC0700323D32 /* Steensgaard.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Steensgaard.cpp; sourceTree = ""; }; DE66ECEB08ABEC0700323D32 /* TopDownClosure.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TopDownClosure.cpp; sourceTree = ""; }; - DE66ED1608ABEC0800323D32 /* Expressions.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Expressions.cpp; sourceTree = ""; }; DE66ED1708ABEC0800323D32 /* InstCount.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = InstCount.cpp; sourceTree = ""; }; DE66ED1808ABEC0800323D32 /* Interval.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Interval.cpp; sourceTree = ""; }; DE66ED1908ABEC0800323D32 /* IntervalPartition.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IntervalPartition.cpp; sourceTree = ""; }; DE66ED1B08ABEC0800323D32 /* Andersens.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Andersens.cpp; sourceTree = ""; }; DE66ED1C08ABEC0800323D32 /* CallGraph.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CallGraph.cpp; sourceTree = ""; }; DE66ED1D08ABEC0800323D32 /* CallGraphSCCPass.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CallGraphSCCPass.cpp; sourceTree = ""; }; - DE66ED2E08ABEC0800323D32 /* FindUnsafePointerTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FindUnsafePointerTypes.cpp; sourceTree = ""; }; DE66ED2F08ABEC0800323D32 /* FindUsedTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FindUsedTypes.cpp; sourceTree = ""; }; DE66ED3008ABEC0800323D32 /* GlobalsModRef.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GlobalsModRef.cpp; sourceTree = ""; }; - DE66ED3208ABEC0800323D32 /* PrintSCC.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PrintSCC.cpp; sourceTree = ""; }; DE66ED3308ABEC0800323D32 /* LoadValueNumbering.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LoadValueNumbering.cpp; sourceTree = ""; }; DE66ED3408ABEC0800323D32 /* LoopInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LoopInfo.cpp; sourceTree = ""; }; DE66ED3608ABEC0800323D32 /* PostDominators.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PostDominators.cpp; sourceTree = ""; }; @@ -163,9 +196,7 @@ DE66ED6F08ABEC2B00323D32 /* ELFWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ELFWriter.cpp; sourceTree = ""; }; DE66ED7008ABEC2B00323D32 /* IntrinsicLowering.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IntrinsicLowering.cpp; sourceTree = ""; }; DE66ED7108ABEC2B00323D32 /* LiveInterval.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiveInterval.cpp; sourceTree = ""; }; - DE66ED7208ABEC2B00323D32 /* LiveInterval.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LiveInterval.h; sourceTree = ""; }; DE66ED7308ABEC2B00323D32 /* LiveIntervalAnalysis.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiveIntervalAnalysis.cpp; sourceTree = ""; }; - DE66ED7408ABEC2B00323D32 /* LiveIntervalAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LiveIntervalAnalysis.h; sourceTree = ""; }; DE66ED7508ABEC2B00323D32 /* LiveVariables.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiveVariables.cpp; sourceTree = ""; }; DE66ED7608ABEC2B00323D32 /* MachineBasicBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MachineBasicBlock.cpp; sourceTree = ""; }; DE66ED7708ABEC2B00323D32 /* MachineCodeEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MachineCodeEmitter.cpp; sourceTree = ""; }; @@ -313,35 +344,6 @@ DE66EF0E08ABEE5E00323D32 /* README */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README; sourceTree = ""; }; DE66EF1008ABEE5E00323D32 /* MRegisterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MRegisterInfo.cpp; sourceTree = ""; }; DE66EF3D08ABEE5F00323D32 /* LICENSE.TXT */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = LICENSE.TXT; sourceTree = ""; }; - DE66EF3F08ABEE5F00323D32 /* PowerPC.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PowerPC.h; sourceTree = ""; }; - DE66EF4008ABEE5F00323D32 /* PowerPC.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = PowerPC.td; sourceTree = ""; }; - DE66EF4108ABEE5F00323D32 /* PowerPCAsmPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PowerPCAsmPrinter.cpp; sourceTree = ""; }; - DE66EF4208ABEE5F00323D32 /* PowerPCBranchSelector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PowerPCBranchSelector.cpp; sourceTree = ""; }; - DE66EF4308ABEE5F00323D32 /* PowerPCFrameInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PowerPCFrameInfo.h; sourceTree = ""; }; - DE66EF4708ABEE5F00323D32 /* PowerPCInstrBuilder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PowerPCInstrBuilder.h; sourceTree = ""; }; - DE66EF4808ABEE5F00323D32 /* PowerPCInstrFormats.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = PowerPCInstrFormats.td; sourceTree = ""; }; - DE66EF4908ABEE5F00323D32 /* PowerPCInstrInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PowerPCInstrInfo.h; sourceTree = ""; }; - DE66EF4A08ABEE5F00323D32 /* PowerPCInstrInfo.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = PowerPCInstrInfo.td; sourceTree = ""; }; - DE66EF4B08ABEE5F00323D32 /* PowerPCJITInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PowerPCJITInfo.h; sourceTree = ""; }; - DE66EF4C08ABEE5F00323D32 /* PowerPCRegisterInfo.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = PowerPCRegisterInfo.td; sourceTree = ""; }; - DE66EF4D08ABEE5F00323D32 /* PowerPCSubtarget.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PowerPCSubtarget.cpp; sourceTree = ""; }; - DE66EF4E08ABEE5F00323D32 /* PowerPCSubtarget.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PowerPCSubtarget.h; sourceTree = ""; }; - DE66EF4F08ABEE5F00323D32 /* PowerPCTargetMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PowerPCTargetMachine.cpp; sourceTree = ""; }; - DE66EF5008ABEE5F00323D32 /* PowerPCTargetMachine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PowerPCTargetMachine.h; sourceTree = ""; }; - DE66EF5108ABEE5F00323D32 /* PPC32.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = PPC32.td; sourceTree = ""; }; - DE66EF5208ABEE5F00323D32 /* PPC32CodeEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PPC32CodeEmitter.cpp; sourceTree = ""; }; - DE66EF5708ABEE5F00323D32 /* PPC32InstrInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PPC32InstrInfo.cpp; sourceTree = ""; }; - DE66EF5808ABEE5F00323D32 /* PPC32InstrInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPC32InstrInfo.h; sourceTree = ""; }; - DE66EF5908ABEE5F00323D32 /* PPC32ISelPattern.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PPC32ISelPattern.cpp; sourceTree = ""; }; - DE66EF5B08ABEE5F00323D32 /* PPC32JITInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PPC32JITInfo.cpp; sourceTree = ""; }; - DE66EF5C08ABEE5F00323D32 /* PPC32JITInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPC32JITInfo.h; sourceTree = ""; }; - DE66EF5D08ABEE5F00323D32 /* PPC32RegisterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PPC32RegisterInfo.cpp; sourceTree = ""; }; - DE66EF5E08ABEE5F00323D32 /* PPC32RegisterInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPC32RegisterInfo.h; sourceTree = ""; }; - DE66EF5F08ABEE5F00323D32 /* PPC32RegisterInfo.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = PPC32RegisterInfo.td; sourceTree = ""; }; - DE66EF6008ABEE5F00323D32 /* PPC32Relocations.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPC32Relocations.h; sourceTree = ""; }; - DE66EF6108ABEE5F00323D32 /* PPC32TargetMachine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPC32TargetMachine.h; sourceTree = ""; }; - DE66EF6208ABEE5F00323D32 /* PPC64.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = PPC64.td; sourceTree = ""; }; - DE66EF6D08ABEE5F00323D32 /* PPC64RegisterInfo.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = PPC64RegisterInfo.td; sourceTree = ""; }; DE66EF6F08ABEE5F00323D32 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README.txt; sourceTree = ""; }; DE66EF8208ABEE5F00323D32 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README.txt; sourceTree = ""; }; DE66EF8308ABEE5F00323D32 /* Skeleton.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Skeleton.h; sourceTree = ""; }; @@ -367,7 +369,6 @@ DE66EFBE08ABEE5F00323D32 /* SparcV8InstrInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SparcV8InstrInfo.cpp; sourceTree = ""; }; DE66EFBF08ABEE5F00323D32 /* SparcV8InstrInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SparcV8InstrInfo.h; sourceTree = ""; }; DE66EFC008ABEE5F00323D32 /* SparcV8InstrInfo.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SparcV8InstrInfo.td; sourceTree = ""; }; - DE66EFC108ABEE5F00323D32 /* SparcV8ISelPattern.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SparcV8ISelPattern.cpp; sourceTree = ""; }; DE66EFC208ABEE5F00323D32 /* SparcV8ISelSimple.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SparcV8ISelSimple.cpp; sourceTree = ""; }; DE66EFC308ABEE5F00323D32 /* SparcV8JITInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SparcV8JITInfo.h; sourceTree = ""; }; DE66EFC408ABEE5F00323D32 /* SparcV8RegisterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SparcV8RegisterInfo.cpp; sourceTree = ""; }; @@ -500,14 +501,6 @@ DE66F0EF08ABEFB300323D32 /* BlockProfiling.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BlockProfiling.cpp; sourceTree = ""; }; DE66F0FE08ABEFB300323D32 /* EdgeProfiling.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = EdgeProfiling.cpp; sourceTree = ""; }; DE66F0FF08ABEFB300323D32 /* EmitFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = EmitFunctions.cpp; sourceTree = ""; }; - DE66F10208ABEFB300323D32 /* CombineBranch.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CombineBranch.cpp; sourceTree = ""; }; - DE66F11308ABEFB300323D32 /* EdgeCode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = EdgeCode.cpp; sourceTree = ""; }; - DE66F11408ABEFB300323D32 /* Graph.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Graph.cpp; sourceTree = ""; }; - DE66F11508ABEFB300323D32 /* Graph.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Graph.h; sourceTree = ""; }; - DE66F11608ABEFB300323D32 /* GraphAuxiliary.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GraphAuxiliary.cpp; sourceTree = ""; }; - DE66F11708ABEFB300323D32 /* InstLoops.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = InstLoops.cpp; sourceTree = ""; }; - DE66F11908ABEFB300323D32 /* ProfilePaths.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ProfilePaths.cpp; sourceTree = ""; }; - DE66F11A08ABEFB300323D32 /* RetracePath.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RetracePath.cpp; sourceTree = ""; }; DE66F11B08ABEFB300323D32 /* ProfilingUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ProfilingUtils.cpp; sourceTree = ""; }; DE66F11C08ABEFB300323D32 /* ProfilingUtils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ProfilingUtils.h; sourceTree = ""; }; DE66F11D08ABEFB300323D32 /* TraceBasicBlocks.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TraceBasicBlocks.cpp; sourceTree = ""; }; @@ -543,12 +536,10 @@ DE66F1A408ABEFB400323D32 /* IndVarSimplify.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IndVarSimplify.cpp; sourceTree = ""; }; DE66F1A508ABEFB400323D32 /* InstructionCombining.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = InstructionCombining.cpp; sourceTree = ""; }; DE66F1A608ABEFB400323D32 /* LICM.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LICM.cpp; sourceTree = ""; }; - DE66F1A708ABEFB400323D32 /* LoopSimplify.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LoopSimplify.cpp; sourceTree = ""; }; DE66F1A808ABEFB400323D32 /* LoopStrengthReduce.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LoopStrengthReduce.cpp; sourceTree = ""; }; DE66F1A908ABEFB400323D32 /* LoopUnroll.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LoopUnroll.cpp; sourceTree = ""; }; DE66F1AA08ABEFB400323D32 /* LoopUnswitch.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LoopUnswitch.cpp; sourceTree = ""; }; DE66F1AB08ABEFB400323D32 /* LowerAllocations.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LowerAllocations.cpp; sourceTree = ""; }; - DE66F1AC08ABEFB400323D32 /* LowerConstantExprs.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LowerConstantExprs.cpp; sourceTree = ""; }; DE66F1AD08ABEFB400323D32 /* LowerGC.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LowerGC.cpp; sourceTree = ""; }; DE66F1AE08ABEFB400323D32 /* LowerInvoke.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LowerInvoke.cpp; sourceTree = ""; }; DE66F1AF08ABEFB400323D32 /* LowerPacked.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LowerPacked.cpp; sourceTree = ""; }; @@ -609,8 +600,6 @@ DE66F20D08ABF03100323D32 /* DSNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DSNode.h; sourceTree = ""; }; DE66F20E08ABF03100323D32 /* DSSupport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DSSupport.h; sourceTree = ""; }; DE66F20F08ABF03100323D32 /* Dominators.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Dominators.h; sourceTree = ""; }; - DE66F21008ABF03100323D32 /* Expressions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Expressions.h; sourceTree = ""; }; - DE66F21108ABF03100323D32 /* FindUnsafePointerTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FindUnsafePointerTypes.h; sourceTree = ""; }; DE66F21208ABF03100323D32 /* FindUsedTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FindUsedTypes.h; sourceTree = ""; }; DE66F21308ABF03100323D32 /* Interval.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Interval.h; sourceTree = ""; }; DE66F21408ABF03100323D32 /* IntervalIterator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IntervalIterator.h; sourceTree = ""; }; @@ -902,8 +891,6 @@ DE81708808CFB44D0093BDEF /* FileParser.y */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.yacc; path = FileParser.y; sourceTree = ""; }; DE81708908CFB44D0093BDEF /* InstrInfoEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = InstrInfoEmitter.cpp; sourceTree = ""; }; DE81708A08CFB44D0093BDEF /* InstrInfoEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InstrInfoEmitter.h; sourceTree = ""; }; - DE81708B08CFB44D0093BDEF /* InstrSelectorEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = InstrSelectorEmitter.cpp; sourceTree = ""; }; - DE81708C08CFB44D0093BDEF /* InstrSelectorEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InstrSelectorEmitter.h; sourceTree = ""; }; DE81708E08CFB44D0093BDEF /* Record.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Record.cpp; sourceTree = ""; }; DE81708F08CFB44D0093BDEF /* Record.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Record.h; sourceTree = ""; }; DE81709008CFB44D0093BDEF /* RegisterInfoEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterInfoEmitter.cpp; sourceTree = ""; }; @@ -911,9 +898,6 @@ DE8170AA08CFB44D0093BDEF /* TableGen.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TableGen.cpp; sourceTree = ""; }; DE8170AB08CFB44D0093BDEF /* TableGenBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TableGenBackend.cpp; sourceTree = ""; }; DE8170AC08CFB44D0093BDEF /* TableGenBackend.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TableGenBackend.h; sourceTree = ""; }; - DE8170C108CFB59B0093BDEF /* PPC32ISelDAGToDAG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PPC32ISelDAGToDAG.cpp; sourceTree = ""; }; - DE8170C408CFB5B20093BDEF /* PPC32ISelLowering.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PPC32ISelLowering.cpp; sourceTree = ""; }; - DE8170C508CFB5B20093BDEF /* PPC32ISelLowering.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPC32ISelLowering.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXGroup section */ @@ -1040,7 +1024,6 @@ DE66ECC108ABEC0700323D32 /* AliasSetTracker.cpp */, DE66ECC208ABEC0700323D32 /* BasicAliasAnalysis.cpp */, DE66ECC308ABEC0700323D32 /* CFGPrinter.cpp */, - DE66ED1608ABEC0800323D32 /* Expressions.cpp */, DE66ED1708ABEC0800323D32 /* InstCount.cpp */, DE66ED1808ABEC0800323D32 /* Interval.cpp */, DE66ED1908ABEC0800323D32 /* IntervalPartition.cpp */, @@ -1084,10 +1067,8 @@ DE66ED1B08ABEC0800323D32 /* Andersens.cpp */, DE66ED1C08ABEC0800323D32 /* CallGraph.cpp */, DE66ED1D08ABEC0800323D32 /* CallGraphSCCPass.cpp */, - DE66ED2E08ABEC0800323D32 /* FindUnsafePointerTypes.cpp */, DE66ED2F08ABEC0800323D32 /* FindUsedTypes.cpp */, DE66ED3008ABEC0800323D32 /* GlobalsModRef.cpp */, - DE66ED3208ABEC0800323D32 /* PrintSCC.cpp */, ); path = IPA; sourceTree = ""; @@ -1101,9 +1082,7 @@ DE66ED6F08ABEC2B00323D32 /* ELFWriter.cpp */, DE66ED7008ABEC2B00323D32 /* IntrinsicLowering.cpp */, DE66ED7108ABEC2B00323D32 /* LiveInterval.cpp */, - DE66ED7208ABEC2B00323D32 /* LiveInterval.h */, DE66ED7308ABEC2B00323D32 /* LiveIntervalAnalysis.cpp */, - DE66ED7408ABEC2B00323D32 /* LiveIntervalAnalysis.h */, DE66ED7508ABEC2B00323D32 /* LiveVariables.cpp */, DE66ED7608ABEC2B00323D32 /* MachineBasicBlock.cpp */, DE66ED7708ABEC2B00323D32 /* MachineCodeEmitter.cpp */, @@ -1402,38 +1381,36 @@ isa = PBXGroup; children = ( DE66EF3D08ABEE5F00323D32 /* LICENSE.TXT */, - DE66EF3F08ABEE5F00323D32 /* PowerPC.h */, - DE66EF4008ABEE5F00323D32 /* PowerPC.td */, - DE66EF4108ABEE5F00323D32 /* PowerPCAsmPrinter.cpp */, - DE66EF4208ABEE5F00323D32 /* PowerPCBranchSelector.cpp */, - DE66EF4308ABEE5F00323D32 /* PowerPCFrameInfo.h */, - DE66EF4708ABEE5F00323D32 /* PowerPCInstrBuilder.h */, - DE66EF4808ABEE5F00323D32 /* PowerPCInstrFormats.td */, - DE66EF4908ABEE5F00323D32 /* PowerPCInstrInfo.h */, - DE66EF4A08ABEE5F00323D32 /* PowerPCInstrInfo.td */, - DE66EF4B08ABEE5F00323D32 /* PowerPCJITInfo.h */, - DE66EF4C08ABEE5F00323D32 /* PowerPCRegisterInfo.td */, - DE66EF4D08ABEE5F00323D32 /* PowerPCSubtarget.cpp */, - DE66EF4E08ABEE5F00323D32 /* PowerPCSubtarget.h */, - DE66EF4F08ABEE5F00323D32 /* PowerPCTargetMachine.cpp */, - DE66EF5008ABEE5F00323D32 /* PowerPCTargetMachine.h */, - DE66EF5108ABEE5F00323D32 /* PPC32.td */, - DE66EF5208ABEE5F00323D32 /* PPC32CodeEmitter.cpp */, - DE66EF5708ABEE5F00323D32 /* PPC32InstrInfo.cpp */, - DE66EF5808ABEE5F00323D32 /* PPC32InstrInfo.h */, - DE8170C108CFB59B0093BDEF /* PPC32ISelDAGToDAG.cpp */, - DE8170C408CFB5B20093BDEF /* PPC32ISelLowering.cpp */, - DE8170C508CFB5B20093BDEF /* PPC32ISelLowering.h */, - DE66EF5908ABEE5F00323D32 /* PPC32ISelPattern.cpp */, - DE66EF5B08ABEE5F00323D32 /* PPC32JITInfo.cpp */, - DE66EF5C08ABEE5F00323D32 /* PPC32JITInfo.h */, - DE66EF5D08ABEE5F00323D32 /* PPC32RegisterInfo.cpp */, - DE66EF5E08ABEE5F00323D32 /* PPC32RegisterInfo.h */, - DE66EF5F08ABEE5F00323D32 /* PPC32RegisterInfo.td */, - DE66EF6008ABEE5F00323D32 /* PPC32Relocations.h */, - DE66EF6108ABEE5F00323D32 /* PPC32TargetMachine.h */, - DE66EF6208ABEE5F00323D32 /* PPC64.td */, - DE66EF6D08ABEE5F00323D32 /* PPC64RegisterInfo.td */, + DE4DA03F091147DD0012D44B /* PPC.h */, + DE4DA040091147DD0012D44B /* PPC.td */, + DE4DA041091147DD0012D44B /* PPCAsmPrinter.cpp */, + DE4DA042091147DD0012D44B /* PPCBranchSelector.cpp */, + DE4DA043091147DD0012D44B /* PPCCodeEmitter.cpp */, + DE4DA044091147DD0012D44B /* PPCFrameInfo.h */, + DE4DA045091147ED0012D44B /* PPCInstrBuilder.h */, + DE4DA046091147ED0012D44B /* PPCInstrFormats.td */, + DE4DA047091147ED0012D44B /* PPCInstrInfo.cpp */, + DE4DA048091147ED0012D44B /* PPCInstrInfo.h */, + DE4DA049091147ED0012D44B /* PPCInstrInfo.td */, + DE4DA04A091147ED0012D44B /* PPCISelDAGToDAG.cpp */, + DE4DA04B091147ED0012D44B /* PPCISelLowering.cpp */, + DE4DA04C091147ED0012D44B /* PPCISelLowering.h */, + DE4DA04D091147ED0012D44B /* PPCISelPattern.cpp */, + DE4DA04E091147ED0012D44B /* PPCJITInfo.cpp */, + DE4DA04F091147ED0012D44B /* PPCJITInfo.h */, + DE4DA050091147ED0012D44B /* PPCRegisterInfo.cpp */, + DE4DA051091147ED0012D44B /* PPCRegisterInfo.h */, + DE4DA052091147ED0012D44B /* PPCRegisterInfo.td */, + DE4DA053091147ED0012D44B /* PPCRelocations.h */, + DE4DA054091147ED0012D44B /* PPCSchedule.td */, + DE4DA055091147ED0012D44B /* PPCScheduleG3.td */, + DE4DA056091147ED0012D44B /* PPCScheduleG4.td */, + DE4DA057091147ED0012D44B /* PPCScheduleG4Plus.td */, + DE4DA058091147ED0012D44B /* PPCScheduleG5.td */, + DE4DA059091147ED0012D44B /* PPCSubtarget.cpp */, + DE4DA05A091147ED0012D44B /* PPCSubtarget.h */, + DE4DA05B091147ED0012D44B /* PPCTargetMachine.cpp */, + DE4DA05C091147ED0012D44B /* PPCTargetMachine.h */, DE66EF6F08ABEE5F00323D32 /* README.txt */, ); path = PowerPC; @@ -1473,7 +1450,6 @@ DE66EFBE08ABEE5F00323D32 /* SparcV8InstrInfo.cpp */, DE66EFBF08ABEE5F00323D32 /* SparcV8InstrInfo.h */, DE66EFC008ABEE5F00323D32 /* SparcV8InstrInfo.td */, - DE66EFC108ABEE5F00323D32 /* SparcV8ISelPattern.cpp */, DE66EFC208ABEE5F00323D32 /* SparcV8ISelSimple.cpp */, DE66EFC308ABEE5F00323D32 /* SparcV8JITInfo.h */, DE66EFC408ABEE5F00323D32 /* SparcV8RegisterInfo.cpp */, @@ -1662,7 +1638,6 @@ DE66F0EE08ABEFB300323D32 /* Instrumentation */ = { isa = PBXGroup; children = ( - DE66F10108ABEFB300323D32 /* ProfilePaths */, DE66F0EF08ABEFB300323D32 /* BlockProfiling.cpp */, DE66F0FE08ABEFB300323D32 /* EdgeProfiling.cpp */, DE66F0FF08ABEFB300323D32 /* EmitFunctions.cpp */, @@ -1674,21 +1649,6 @@ path = Instrumentation; sourceTree = ""; }; - DE66F10108ABEFB300323D32 /* ProfilePaths */ = { - isa = PBXGroup; - children = ( - DE66F10208ABEFB300323D32 /* CombineBranch.cpp */, - DE66F11308ABEFB300323D32 /* EdgeCode.cpp */, - DE66F11408ABEFB300323D32 /* Graph.cpp */, - DE66F11508ABEFB300323D32 /* Graph.h */, - DE66F11608ABEFB300323D32 /* GraphAuxiliary.cpp */, - DE66F11708ABEFB300323D32 /* InstLoops.cpp */, - DE66F11908ABEFB300323D32 /* ProfilePaths.cpp */, - DE66F11A08ABEFB300323D32 /* RetracePath.cpp */, - ); - path = ProfilePaths; - sourceTree = ""; - }; DE66F11F08ABEFB300323D32 /* IPO */ = { isa = PBXGroup; children = ( @@ -1729,12 +1689,10 @@ DE66F1A408ABEFB400323D32 /* IndVarSimplify.cpp */, DE66F1A508ABEFB400323D32 /* InstructionCombining.cpp */, DE66F1A608ABEFB400323D32 /* LICM.cpp */, - DE66F1A708ABEFB400323D32 /* LoopSimplify.cpp */, DE66F1A808ABEFB400323D32 /* LoopStrengthReduce.cpp */, DE66F1A908ABEFB400323D32 /* LoopUnroll.cpp */, DE66F1AA08ABEFB400323D32 /* LoopUnswitch.cpp */, DE66F1AB08ABEFB400323D32 /* LowerAllocations.cpp */, - DE66F1AC08ABEFB400323D32 /* LowerConstantExprs.cpp */, DE66F1AD08ABEFB400323D32 /* LowerGC.cpp */, DE66F1AE08ABEFB400323D32 /* LowerInvoke.cpp */, DE66F1AF08ABEFB400323D32 /* LowerPacked.cpp */, @@ -1764,6 +1722,7 @@ DE66F1E008ABEFB400323D32 /* DemoteRegToStack.cpp */, DE66F1E108ABEFB400323D32 /* InlineFunction.cpp */, DE66F1E208ABEFB400323D32 /* Local.cpp */, + DE4DA0390911476D0012D44B /* LoopSimplify.cpp */, DE66F1E408ABEFB400323D32 /* PromoteMemoryToRegister.cpp */, DE66F1E508ABEFB400323D32 /* SimplifyCFG.cpp */, DE66F1E608ABEFB400323D32 /* UnifyFunctionExitNodes.cpp */, @@ -1859,8 +1818,6 @@ DE66F20808ABF03100323D32 /* ConstantsScanner.h */, DE66F20908ABF03100323D32 /* DataStructure */, DE66F20F08ABF03100323D32 /* Dominators.h */, - DE66F21008ABF03100323D32 /* Expressions.h */, - DE66F21108ABF03100323D32 /* FindUnsafePointerTypes.h */, DE66F21208ABF03100323D32 /* FindUsedTypes.h */, DE66F21308ABF03100323D32 /* Interval.h */, DE66F21408ABF03100323D32 /* IntervalIterator.h */, @@ -1927,6 +1884,8 @@ DE66F23708ABF03100323D32 /* ELFWriter.h */, DE66F23808ABF03100323D32 /* InstrScheduling.h */, DE66F23908ABF03100323D32 /* IntrinsicLowering.h */, + DE4DA03C091147920012D44B /* LiveInterval.h */, + DE4DA03D091147920012D44B /* LiveIntervalAnalysis.h */, DE66F23A08ABF03100323D32 /* LiveVariables.h */, DE66F23B08ABF03100323D32 /* MachineBasicBlock.h */, DE66F23C08ABF03100323D32 /* MachineCodeEmitter.h */, @@ -2113,6 +2072,7 @@ DE66F2BF08ABF14400323D32 /* AnalysisWrappers.cpp */, DE66F2C008ABF14400323D32 /* analyze.cpp */, DE66F2C908ABF14400323D32 /* GraphPrinters.cpp */, + DE4DA03E091147C00012D44B /* PrintSCC.cpp */, ); path = analyze; sourceTree = ""; @@ -2316,12 +2276,12 @@ DE81708808CFB44D0093BDEF /* FileParser.y */, DE81708908CFB44D0093BDEF /* InstrInfoEmitter.cpp */, DE81708A08CFB44D0093BDEF /* InstrInfoEmitter.h */, - DE81708B08CFB44D0093BDEF /* InstrSelectorEmitter.cpp */, - DE81708C08CFB44D0093BDEF /* InstrSelectorEmitter.h */, DE81708E08CFB44D0093BDEF /* Record.cpp */, DE81708F08CFB44D0093BDEF /* Record.h */, DE81709008CFB44D0093BDEF /* RegisterInfoEmitter.cpp */, DE81709108CFB44D0093BDEF /* RegisterInfoEmitter.h */, + DE4DA065091148520012D44B /* SubtargetEmitter.cpp */, + DE4DA066091148520012D44B /* SubtargetEmitter.h */, DE8170AA08CFB44D0093BDEF /* TableGen.cpp */, DE8170AB08CFB44D0093BDEF /* TableGenBackend.cpp */, DE8170AC08CFB44D0093BDEF /* TableGenBackend.h */, From bocchino at cs.uiuc.edu Wed Nov 16 12:31:16 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:31:16 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/autoconf/configure.ac Message-ID: <200511161831.MAA20561@zion.cs.uiuc.edu> Changes in directory llvm/autoconf: configure.ac updated: 1.195.2.2 -> 1.195.2.3 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+5 -4) configure.ac | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) Index: llvm/autoconf/configure.ac diff -u llvm/autoconf/configure.ac:1.195.2.2 llvm/autoconf/configure.ac:1.195.2.3 --- llvm/autoconf/configure.ac:1.195.2.2 Tue Oct 18 15:08:37 2005 +++ llvm/autoconf/configure.ac Wed Nov 16 12:31:05 2005 @@ -31,12 +31,12 @@ dnl===-----------------------------------------------------------------------=== dnl Initialize autoconf and define the package name, version number and dnl email address for reporting bugs. -AC_INIT([[llvm]],[[1.6cvs]],[llvmbugs at cs.uiuc.edu]) +AC_INIT([[llvm]],[[1.7cvs]],[llvmbugs at cs.uiuc.edu]) dnl Provide a copyright substitution and ensure the copyright notice is included dnl in the output of --version option of the generated configure script. AC_SUBST(LLVM_COPYRIGHT,["Copyright (c) 2003-2005 University of Illinois at Urbana-Champaign."]) -AC_COPYRIGHT($LLVM_COPYRIGHT) +AC_COPYRIGHT([Copyright (c) 2003-2005 University of Illinois at Urbana-Champaign.]) dnl Indicate that we require autoconf 2.59 or later. Ths is needed because we dnl use some autoconf macros only available in 2.59. @@ -324,7 +324,7 @@ [Define to path to Graphviz program if found or 'echo Graphviz' otherwise]) fi AC_PATH_PROG(GV, [gv], [echo gv]) -if test "$GRAPHVIZ" != "echo gv" ; then +if test "$GV" != "echo gv" ; then AC_DEFINE([HAVE_GV],[1],[Define if the gv program is available]) AC_DEFINE_UNQUOTED([LLVM_PATH_GV],"$GV", [Define to path to gv program if found or 'echo gv' otherwise]) @@ -487,6 +487,7 @@ AC_CHECK_HEADERS([dlfcn.h execinfo.h fcntl.h inttypes.h limits.h link.h]) AC_CHECK_HEADERS([malloc.h signal.h stdint.h unistd.h utime.h windows.h]) AC_CHECK_HEADERS([sys/mman.h sys/param.h sys/resource.h sys/time.h sys/types.h]) +AC_CHECK_HEADERS([malloc/malloc.h]) AC_CHECK_HEADERS([rw/stdex/hash_map.h rw/stdex/hash_set.h]) if test "$ENABLE_THREADS" -eq 1 ; then AC_CHECK_HEADERS(pthread.h) @@ -516,7 +517,7 @@ AC_CHECK_FUNCS([backtrace getcwd getpagesize getrusage gettimeofday ]) AC_CHECK_FUNCS([isatty mkdtemp mkstemp mktemp ]) AC_CHECK_FUNCS([realpath sbrk setrlimit strdup strerror strerror_r ]) -AC_CHECK_FUNCS([strtoll strtoq sysconf]) +AC_CHECK_FUNCS([strtoll strtoq sysconf malloc_zone_statistics ]) AC_C_PRINTF_A AC_FUNC_ALLOCA AC_FUNC_RAND48 From bocchino at cs.uiuc.edu Wed Nov 16 12:31:22 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:31:22 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/include/llvm/AbstractTypeUser.h BasicBlock.h Constant.h DerivedTypes.h Function.h GlobalValue.h Instruction.h Instructions.h Intrinsics.h Module.h Type.h Message-ID: <200511161831.MAA20619@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: AbstractTypeUser.h updated: 1.25 -> 1.25.4.1 BasicBlock.h updated: 1.56 -> 1.56.2.1 Constant.h updated: 1.25 -> 1.25.2.1 DerivedTypes.h updated: 1.68.4.1 -> 1.68.4.2 Function.h updated: 1.66 -> 1.66.4.1 GlobalValue.h updated: 1.23 -> 1.23.4.1 Instruction.h updated: 1.68 -> 1.68.2.1 Instructions.h updated: 1.27.2.1 -> 1.27.2.2 Intrinsics.h updated: 1.32 -> 1.32.4.1 Module.h updated: 1.62 -> 1.62.4.1 Type.h updated: 1.77.4.1 -> 1.77.4.2 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+109 -135) AbstractTypeUser.h | 8 ----- BasicBlock.h | 2 - Constant.h | 2 - DerivedTypes.h | 71 ++--------------------------------------------------- Function.h | 2 - GlobalValue.h | 19 +++++++++++--- Instruction.h | 2 - Instructions.h | 40 +++++++++++++++++++++++------ Intrinsics.h | 9 +++--- Module.h | 24 +++++++++-------- Type.h | 65 +++++++++++++++++++++++++++--------------------- 11 files changed, 109 insertions(+), 135 deletions(-) Index: llvm/include/llvm/AbstractTypeUser.h diff -u llvm/include/llvm/AbstractTypeUser.h:1.25 llvm/include/llvm/AbstractTypeUser.h:1.25.4.1 --- llvm/include/llvm/AbstractTypeUser.h:1.25 Thu Apr 21 22:20:18 2005 +++ llvm/include/llvm/AbstractTypeUser.h Wed Nov 16 12:31:11 2005 @@ -117,14 +117,6 @@ // operator-> - Allow user to dereference handle naturally... inline const Type *operator->() const { return Ty; } - - // removeUserFromConcrete - This function should be called when the User is - // notified that our type is refined... and the type is being refined to - // itself, which is now a concrete type. When a type becomes concrete like - // this, we MUST remove ourself from the AbstractTypeUser list, even though - // the type is apparently concrete. - // - void removeUserFromConcrete(); }; Index: llvm/include/llvm/BasicBlock.h diff -u llvm/include/llvm/BasicBlock.h:1.56 llvm/include/llvm/BasicBlock.h:1.56.2.1 --- llvm/include/llvm/BasicBlock.h:1.56 Fri Aug 12 17:13:27 2005 +++ llvm/include/llvm/BasicBlock.h Wed Nov 16 12:31:11 2005 @@ -139,7 +139,7 @@ void print(std::ostream &OS, AssemblyAnnotationWriter *AAW) const; /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const BasicBlock *BB) { return true; } + static inline bool classof(const BasicBlock *) { return true; } static inline bool classof(const Value *V) { return V->getValueType() == Value::BasicBlockVal; } Index: llvm/include/llvm/Constant.h diff -u llvm/include/llvm/Constant.h:1.25 llvm/include/llvm/Constant.h:1.25.2.1 --- llvm/include/llvm/Constant.h:1.25 Tue Oct 4 13:12:13 2005 +++ llvm/include/llvm/Constant.h Wed Nov 16 12:31:11 2005 @@ -75,7 +75,7 @@ /// use Value::replaceAllUsesWith, which automatically dispatches to this /// method as needed. /// - virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { + virtual void replaceUsesOfWithOnConstant(Value *, Value *, Use *) { // 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/DerivedTypes.h diff -u llvm/include/llvm/DerivedTypes.h:1.68.4.1 llvm/include/llvm/DerivedTypes.h:1.68.4.2 --- llvm/include/llvm/DerivedTypes.h:1.68.4.1 Tue Oct 18 14:21:56 2005 +++ llvm/include/llvm/DerivedTypes.h Wed Nov 16 12:31:11 2005 @@ -29,22 +29,14 @@ class ArrayValType; class StructValType; class PointerValType; -class StreamValType; class VectorValType; class FixedVectorValType; -class DerivedType : public Type, public AbstractTypeUser { - // AbstractTypeUsers - Implement a list of the users that need to be notified - // if I am a type, and I get resolved into a more concrete type. - // - mutable std::vector AbstractTypeUsers; +class DerivedType : public Type { friend class Type; protected: - DerivedType(TypeID id) : Type("", id) {} - ~DerivedType() { - assert(AbstractTypeUsers.empty()); - } + DerivedType(TypeID id) : Type(id) {} /// notifyUsesThatTypeBecameConcrete - Notify AbstractTypeUsers of this type /// that the current type has transitioned from being abstract to being @@ -58,12 +50,6 @@ /// void dropAllTypeUses(); - void RefCountIsZero() const { - if (AbstractTypeUsers.empty()) - delete this; - } - - public: //===--------------------------------------------------------------------===// @@ -71,22 +57,6 @@ // are managed by (add|remove)AbstractTypeUser. See comments in // AbstractTypeUser.h for more information. - /// addAbstractTypeUser - Notify an abstract type that there is a new user of - /// it. This function is called primarily by the PATypeHandle class. - /// - void addAbstractTypeUser(AbstractTypeUser *U) const { - assert(isAbstract() && "addAbstractTypeUser: Current type not abstract!"); - AbstractTypeUsers.push_back(U); - } - - /// removeAbstractTypeUser - Notify an abstract type that a user of the class - /// no longer has a handle to the type. This function is called primarily by - /// the PATypeHandle class. When there are no users of the abstract type, it - /// is annihilated, because there is no way to get a reference to it ever - /// again. - /// - void removeAbstractTypeUser(AbstractTypeUser *U) const; - /// refineAbstractTypeTo - This function is used to when it is discovered that /// the 'this' abstract type is actually equivalent to the NewType specified. /// This causes all users of 'this' to switch to reference the more concrete @@ -176,7 +146,6 @@ return T->getTypeID() == ArrayTyID || T->getTypeID() == StructTyID || T->getTypeID() == PointerTyID || - T->getTypeID() == StreamTyID || T->getTypeID() == VectorTyID || T->getTypeID() == FixedVectorTyID; } @@ -268,7 +237,6 @@ static inline bool classof(const Type *T) { return T->getTypeID() == ArrayTyID || T->getTypeID() == PointerTyID || - T->getTypeID() == StreamTyID || T->getTypeID() == VectorTyID || T->getTypeID() == FixedVectorTyID; } @@ -311,40 +279,6 @@ } }; -/// StreamType - Class to represent vector types -/// -class StreamType : public SequentialType { - friend class TypeMap; - - StreamType(const StreamType &); // Do not implement - const StreamType &operator=(const StreamType &); // Do not implement - -protected: - /// This should really be private, but it squelches a bogus warning - /// from GCC to make them protected: warning: `class StreamType' only - /// defines private constructors and has no friends - /// - /// Private ctor - Only can be created by a static member... - /// - StreamType(const Type *ElType); - -public: - /// StreamType::get - This static method is the primary way to construct a - /// StreamType - /// - static StreamType *get(const Type *ElementType); - - // Implement the AbstractTypeUser interface. - virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); - virtual void typeBecameConcrete(const DerivedType *AbsTy); - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const StreamType *T) { return true; } - static inline bool classof(const Type *T) { - return T->getTypeID() == StreamTyID; - } -}; - /// VectorType - Class to represent vector types /// class VectorType : public SequentialType { @@ -387,6 +321,7 @@ } }; + /// FixedVectorType - Class to represent vectors with fixed lengths /// class FixedVectorType : public VectorType { Index: llvm/include/llvm/Function.h diff -u llvm/include/llvm/Function.h:1.66 llvm/include/llvm/Function.h:1.66.4.1 --- llvm/include/llvm/Function.h:1.66 Sun May 15 20:49:12 2005 +++ llvm/include/llvm/Function.h Wed Nov 16 12:31:11 2005 @@ -57,8 +57,6 @@ typedef ArgumentListType::iterator arg_iterator; typedef ArgumentListType::const_iterator const_arg_iterator; - typedef arg_iterator aiterator; // legacy, deprecated - typedef const_arg_iterator const_aiterator; // legacy, deprecated private: // Important things that make up a function! Index: llvm/include/llvm/GlobalValue.h diff -u llvm/include/llvm/GlobalValue.h:1.23 llvm/include/llvm/GlobalValue.h:1.23.4.1 --- llvm/include/llvm/GlobalValue.h:1.23 Thu Apr 21 15:11:51 2005 +++ llvm/include/llvm/GlobalValue.h Wed Nov 16 12:31:11 2005 @@ -38,15 +38,28 @@ protected: GlobalValue(const Type *Ty, ValueTy vty, Use *Ops, unsigned NumOps, LinkageTypes linkage, const std::string &name = "") - : Constant(Ty, vty, Ops, NumOps, name), Linkage(linkage), Parent(0) { } + : Constant(Ty, vty, Ops, NumOps, name), + Parent(0), Linkage(linkage), Alignment(0) { } - LinkageTypes Linkage; // The linkage of this global Module *Parent; + LinkageTypes Linkage; // The linkage of this global + unsigned Alignment; // Alignment of this symbol, must be power of two + std::string Section; // Section to emit this into, empty mean default public: ~GlobalValue() { removeDeadConstantUsers(); // remove any dead constants using this. } + unsigned getAlignment() const { return Alignment; } + void setAlignment(unsigned Align) { + assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); + Alignment = Align; + } + + bool hasSection() const { return !Section.empty(); } + const std::string &getSection() const { return Section; } + void setSection(const std::string &S) { Section = S; } + /// If the usage is empty (except transitively dead constants), then this /// global value can can be safely deleted since the destructor will /// delete the dead constants as well. @@ -101,7 +114,7 @@ void removeDeadConstantUsers(); // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const GlobalValue *T) { return true; } + static inline bool classof(const GlobalValue *) { return true; } static inline bool classof(const Value *V) { return V->getValueType() == Value::FunctionVal || V->getValueType() == Value::GlobalVariableVal; Index: llvm/include/llvm/Instruction.h diff -u llvm/include/llvm/Instruction.h:1.68 llvm/include/llvm/Instruction.h:1.68.2.1 --- llvm/include/llvm/Instruction.h:1.68 Mon Aug 8 00:21:33 2005 +++ llvm/include/llvm/Instruction.h Wed Nov 16 12:31:11 2005 @@ -157,7 +157,7 @@ void print(std::ostream &OS, AssemblyAnnotationWriter *AAW) const; /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { return true; } + static inline bool classof(const Instruction *) { return true; } static inline bool classof(const Value *V) { return V->getValueType() >= Value::InstructionVal; } Index: llvm/include/llvm/Instructions.h diff -u llvm/include/llvm/Instructions.h:1.27.2.1 llvm/include/llvm/Instructions.h:1.27.2.2 --- llvm/include/llvm/Instructions.h:1.27.2.1 Tue Oct 18 14:21:56 2005 +++ llvm/include/llvm/Instructions.h Wed Nov 16 12:31:11 2005 @@ -35,10 +35,11 @@ /// AllocaInst. /// class AllocationInst : public UnaryInstruction { + unsigned Alignment; protected: - AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, + AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, unsigned Align, const std::string &Name = "", Instruction *InsertBefore = 0); - AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, + AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, unsigned Align, const std::string &Name, BasicBlock *InsertAtEnd); public: @@ -65,6 +66,15 @@ /// const Type *getAllocatedType() const; + /// getAlignment - Return the alignment of the memory that is being allocated + /// by the instruction. + /// + unsigned getAlignment() const { return Alignment; } + void setAlignment(unsigned Align) { + assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); + Alignment = Align; + } + virtual Instruction *clone() const = 0; // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -91,11 +101,18 @@ explicit MallocInst(const Type *Ty, Value *ArraySize = 0, const std::string &Name = "", Instruction *InsertBefore = 0) - : AllocationInst(Ty, ArraySize, Malloc, Name, InsertBefore) {} + : AllocationInst(Ty, ArraySize, Malloc, 0, Name, InsertBefore) {} MallocInst(const Type *Ty, Value *ArraySize, const std::string &Name, BasicBlock *InsertAtEnd) - : AllocationInst(Ty, ArraySize, Malloc, Name, InsertAtEnd) {} - + : AllocationInst(Ty, ArraySize, Malloc, 0, Name, InsertAtEnd) {} + MallocInst(const Type *Ty, Value *ArraySize, unsigned Align, + const std::string &Name, BasicBlock *InsertAtEnd) + : AllocationInst(Ty, ArraySize, Malloc, Align, Name, InsertAtEnd) {} + explicit MallocInst(const Type *Ty, Value *ArraySize, unsigned Align, + const std::string &Name = "", + Instruction *InsertBefore = 0) + : AllocationInst(Ty, ArraySize, Malloc, Align, Name, InsertBefore) {} + virtual MallocInst *clone() const; // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -121,11 +138,18 @@ explicit AllocaInst(const Type *Ty, Value *ArraySize = 0, const std::string &Name = "", Instruction *InsertBefore = 0) - : AllocationInst(Ty, ArraySize, Alloca, Name, InsertBefore) {} + : AllocationInst(Ty, ArraySize, Alloca, 0, Name, InsertBefore) {} AllocaInst(const Type *Ty, Value *ArraySize, const std::string &Name, BasicBlock *InsertAtEnd) - : AllocationInst(Ty, ArraySize, Alloca, Name, InsertAtEnd) {} - + : AllocationInst(Ty, ArraySize, Alloca, 0, Name, InsertAtEnd) {} + AllocaInst(const Type *Ty, Value *ArraySize, unsigned Align, + const std::string &Name, BasicBlock *InsertAtEnd) + : AllocationInst(Ty, ArraySize, Alloca, Align, Name, InsertAtEnd) {} + explicit AllocaInst(const Type *Ty, Value *ArraySize, unsigned Align, + const std::string &Name = "", + Instruction *InsertBefore = 0) + : AllocationInst(Ty, ArraySize, Alloca, Align, Name, InsertBefore) {} + virtual AllocaInst *clone() const; // Methods for support type inquiry through isa, cast, and dyn_cast: Index: llvm/include/llvm/Intrinsics.h diff -u llvm/include/llvm/Intrinsics.h:1.32 llvm/include/llvm/Intrinsics.h:1.32.4.1 --- llvm/include/llvm/Intrinsics.h:1.32 Tue May 3 12:19:29 2005 +++ llvm/include/llvm/Intrinsics.h Wed Nov 16 12:31:11 2005 @@ -32,10 +32,11 @@ vacopy, // Used to implement the va_copy macro in C // Code generator intrinsics. - returnaddress, // Yields the return address of a dynamic call frame - frameaddress, // Yields the frame address of a dynamic call frame - prefetch, // Prefetch a value into the cache - pcmarker, // Export a PC from near the marker + returnaddress, // Yields the return address of a dynamic call frame + frameaddress, // Yields the frame address of a dynamic call frame + prefetch, // Prefetch a value into the cache + pcmarker, // Export a PC from near the marker + readcyclecounter, // Read cycle counter register // setjmp/longjmp intrinsics. setjmp, // Used to represent a setjmp call in C Index: llvm/include/llvm/Module.h diff -u llvm/include/llvm/Module.h:1.62 llvm/include/llvm/Module.h:1.62.4.1 --- llvm/include/llvm/Module.h:1.62 Sun May 15 20:49:23 2005 +++ llvm/include/llvm/Module.h Wed Nov 16 12:31:11 2005 @@ -22,6 +22,7 @@ #include "llvm/Function.h" #include "llvm/GlobalVariable.h" #include "llvm/ADT/SetVector.h" +#include "llvm/Support/DataTypes.h" namespace llvm { @@ -51,17 +52,15 @@ typedef iplist FunctionListType; typedef SetVector LibraryListType; - // Global Variable iterators... - typedef GlobalListType::iterator global_iterator; - typedef GlobalListType::const_iterator const_global_iterator; - typedef global_iterator giterator; // these are legacy, deprecated - typedef const_global_iterator const_giterator; + // Global Variable iterators. + typedef GlobalListType::iterator global_iterator; + typedef GlobalListType::const_iterator const_global_iterator; - // Function iterators... + // Function iterators. typedef FunctionListType::iterator iterator; typedef FunctionListType::const_iterator const_iterator; - // Library list iterators + // Library list iterators. typedef LibraryListType::const_iterator lib_iterator; enum Endianness { AnyEndianness, LittleEndian, BigEndian }; @@ -86,9 +85,11 @@ Module(const std::string &ModuleID); ~Module(); - const std::string& getModuleIdentifier() const { return ModuleID; } - const std::string& getTargetTriple() const { return TargetTriple; } - void setTargetTriple(const std::string& T) { TargetTriple = T; } + const std::string &getModuleIdentifier() const { return ModuleID; } + void setModuleIdentifier(const std::string &ID) { ModuleID = ID; } + + const std::string &getTargetTriple() const { return TargetTriple; } + void setTargetTriple(const std::string &T) { TargetTriple = T; } /// Target endian information... Endianness getEndianness() const { return Endian; } @@ -111,7 +112,8 @@ /// 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,...); + Function *getOrInsertFunction(const std::string &Name, const Type *RetTy,...) + END_WITH_NULL; /// getFunction - Look up the specified function in the module symbol table. /// If it does not exist, return null. Index: llvm/include/llvm/Type.h diff -u llvm/include/llvm/Type.h:1.77.4.1 llvm/include/llvm/Type.h:1.77.4.2 --- llvm/include/llvm/Type.h:1.77.4.1 Tue Oct 18 14:21:56 2005 +++ llvm/include/llvm/Type.h Wed Nov 16 12:31:11 2005 @@ -48,9 +48,9 @@ class OpaqueType; class PointerType; class StructType; -class FixedVectorType; +class TypeMapBase; -class Type { +class Type : public AbstractTypeUser { public: ///===-------------------------------------------------------------------===// /// Definitions of all of the base types for the Type system. Based on this @@ -85,7 +85,7 @@ private: TypeID ID : 8; // The current base type of this type. - bool Abstract; // True if type contains an OpaqueType + bool Abstract : 1; // True if type contains an OpaqueType /// RefCount - This counts the number of PATypeHolders that are pointing to /// this type. When this number falls to zero, if the type is abstract and @@ -96,17 +96,16 @@ const Type *getForwardedTypeInternal() const; protected: - Type(const std::string& Name, TypeID id); - virtual ~Type() {} + Type(const char *Name, TypeID id); + Type(TypeID id) : ID(id), Abstract(false), RefCount(0), ForwardType(0) {} + virtual ~Type() { + assert(AbstractTypeUsers.empty()); + } /// Types can become nonabstract later, if they are refined. /// inline void setAbstract(bool Val) { Abstract = Val; } - // PromoteAbstractToConcrete - This is an internal method used to calculate - // change "Abstract" from true to false when types are refined. - void PromoteAbstractToConcrete(); - unsigned getRefCount() const { return RefCount; } /// ForwardType - This field is used to implement the union find scheme for @@ -123,6 +122,10 @@ /// not contain any elements (most are derived). std::vector ContainedTys; + /// AbstractTypeUsers - Implement a list of the users that need to be notified + /// if I am a type, and I get resolved into a more concrete type. + /// + mutable std::vector AbstractTypeUsers; public: void print(std::ostream &O) const; @@ -305,15 +308,6 @@ /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Type *T) { return true; } - // Virtual methods used by callbacks below. These should only be implemented - // in the DerivedType class. - virtual void addAbstractTypeUser(AbstractTypeUser *U) const { - abort(); // Only on derived types! - } - virtual void removeAbstractTypeUser(AbstractTypeUser *U) const { - abort(); // Only on derived types! - } - void addRef() const { assert(isAbstract() && "Cannot add a reference to a non-abstract type!"); ++RefCount; @@ -325,9 +319,25 @@ // If this is the last PATypeHolder using this object, and there are no // PATypeHandles using it, the type is dead, delete it now. - if (--RefCount == 0) - RefCountIsZero(); + if (--RefCount == 0 && AbstractTypeUsers.empty()) + delete this; } + + /// addAbstractTypeUser - Notify an abstract type that there is a new user of + /// it. This function is called primarily by the PATypeHandle class. + /// + void addAbstractTypeUser(AbstractTypeUser *U) const { + assert(isAbstract() && "addAbstractTypeUser: Current type not abstract!"); + AbstractTypeUsers.push_back(U); + } + + /// removeAbstractTypeUser - Notify an abstract type that a user of the class + /// no longer has a handle to the type. This function is called primarily by + /// the PATypeHandle class. When there are no users of the abstract type, it + /// is annihilated, because there is no way to get a reference to it ever + /// again. + /// + void removeAbstractTypeUser(AbstractTypeUser *U) const; /// clearAllTypeMaps - This method frees all internal memory used by the /// type subsystem, which can be used in environments where this memory is @@ -340,10 +350,14 @@ /// their size is relatively uncommon, move this operation out of line. bool isSizedDerivedType() const; - virtual void RefCountIsZero() const { - abort(); // only on derived types! - } + virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); + virtual void typeBecameConcrete(const DerivedType *AbsTy); +protected: + // PromoteAbstractToConcrete - This is an internal method used to calculate + // change "Abstract" from true to false when types are refined. + void PromoteAbstractToConcrete(); + friend class TypeMapBase; }; //===----------------------------------------------------------------------===// @@ -367,11 +381,6 @@ Ty->removeAbstractTypeUser(User); } -inline void PATypeHandle::removeUserFromConcrete() { - if (!Ty->isAbstract()) - Ty->removeAbstractTypeUser(User); -} - // Define inline methods for PATypeHolder... inline void PATypeHolder::addRef() { From bocchino at cs.uiuc.edu Wed Nov 16 12:31:19 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:31:19 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/docs/BytecodeFormat.html CFEBuildInstrs.html CodeGenerator.html CommandLine.html ExtendingLLVM.html GettingStarted.html GettingStartedVS.html LangRef.html MakefileGuide.html ProgrammersManual.html Projects.html ReleaseNotes.html TableGenFundamentals.html Message-ID: <200511161831.MAA20592@zion.cs.uiuc.edu> Changes in directory llvm/docs: BytecodeFormat.html updated: 1.41 -> 1.41.4.1 CFEBuildInstrs.html updated: 1.53 -> 1.53.2.1 CodeGenerator.html updated: 1.27 -> 1.27.2.1 CommandLine.html updated: 1.38 -> 1.38.2.1 ExtendingLLVM.html updated: 1.18 -> 1.18.4.1 GettingStarted.html updated: 1.120 -> 1.120.2.1 GettingStartedVS.html updated: 1.4 -> 1.4.4.1 LangRef.html updated: 1.112.2.1 -> 1.112.2.2 MakefileGuide.html updated: 1.25 -> 1.25.4.1 ProgrammersManual.html updated: 1.87 -> 1.87.2.1 Projects.html updated: 1.18 -> 1.18.4.1 ReleaseNotes.html updated: 1.333 -> 1.333.2.1 TableGenFundamentals.html updated: 1.13 -> 1.13.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+569 -319) BytecodeFormat.html | 428 +++++++++++++++++++++++++++++++--------------- CFEBuildInstrs.html | 7 CodeGenerator.html | 4 CommandLine.html | 4 ExtendingLLVM.html | 4 GettingStarted.html | 5 GettingStartedVS.html | 31 +-- LangRef.html | 195 ++++++++++++++++---- MakefileGuide.html | 4 ProgrammersManual.html | 70 +++---- Projects.html | 8 ReleaseNotes.html | 122 ++++--------- TableGenFundamentals.html | 6 13 files changed, 569 insertions(+), 319 deletions(-) Index: llvm/docs/BytecodeFormat.html diff -u llvm/docs/BytecodeFormat.html:1.41 llvm/docs/BytecodeFormat.html:1.41.4.1 --- llvm/docs/BytecodeFormat.html:1.41 Fri May 13 20:30:15 2005 +++ llvm/docs/BytecodeFormat.html Wed Nov 16 12:31:07 2005 @@ -39,8 +39,8 @@
  • Global Constant Pool
  • Function Definition
  • Compaction Table
  • -
  • Instruction List
  • -
  • Instruction Opcodes
  • +
  • Instructions List
  • +
  • Instructions
  • Symbol Table
  • @@ -732,7 +732,7 @@

    Of particular note, the bytecode format number is simply a 28-bit -monotonically increase integer that identifies the version of the bytecode +monotonically increasing integer that identifies the version of the bytecode format (which is not directly related to the LLVM release number). The bytecode versions defined so far are (note that this document only describes the latest version, 1.3):

    @@ -740,7 +740,9 @@
  • #0: LLVM 1.0 & 1.1
  • #1: LLVM 1.2
  • #2: LLVM 1.2.5 (not released)
  • -
  • #3: LLVM 1.3
    +
  • #3: LLVM 1.3
  • +
  • #4: LLVM 1.3.x (not released)
  • +
  • #5: LLVM 1.4, 1.5, 1.6
  • Note that we plan to eventually expand the target description @@ -967,22 +969,29 @@ occurring in the module. - llist(string)
    + llist(string)
    - A length list + A length list of strings that specify the names of the libraries that this module depends upon.
    - string
    + string
    - The target + The target triple for the module (blank means no target triple specified, i.e. a platform independent module).
    + + llist(string)
    + + A length list +of strings that defines a table of section strings for globals. A global's +SectionID is an index into this table.
    + + @@ -990,12 +999,16 @@

    +
    +

    Global variables are written using an uint32_vbr -that encodes information about the global variable and a list of the -constant initializers for the global var, if any.

    +that encodes information about the global variable, an optional extension vbr, +and a an optional initializers for the global var.

    +

    The table below provides the bit layout of the first uint32_vbr that describes the global variable.

    + @@ -1023,8 +1036,65 @@
    -

    The table below provides the format of the constant initializers for -the global variable field, if it has one.

    + +

    When the Linkage type is set to 3 (internal) and the initializer field is set +to 0 (an invalid combination), an extension word follows the first uint32_vbr which encodes the real linkage and init flag, +and can includes more information:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TypeDescription
    bit(0)Has initializer? Indicates the real value of the "Has + initializer" field for the global.
    bit(2-4)Linkage type: Indicates the real value of the "linkage + type" field for the global.
    bit(4-8)The log-base-2 of the alignment for the global.
    bit(9)If this bit is set, a SectionID follows this vbr.
    bit(10-31)Currently unassigned.
    + +

    If the SectionID bit is set above, the following field is included:

    + + + + + + + + + + + + +
    TypeDescription
    uint32_vbr + An optional section ID number, specifying the string + to use for the section of the global. This an index (+1) of an entry + into the SectionID llist in the Module Global + Info block. If this value is 0 or not present, the global has an + empty section string.
    + +

    If the "Has initializer" field is set, the following field is included:

    + @@ -1032,10 +1102,10 @@ - - +
    Description
    (zlist(uint32_vbr))? + uint32_vbr An optional zero-terminated list of value slot -numbers of the global variable's constant initializer.An optional value slot number for the global + variable's constant initializer.
    @@ -1046,7 +1116,8 @@

    Functions are written using an uint32_vbr -that encodes information about the function and a set of flags.

    +that encodes information about the function and a set of flags. If needed, +an extension word may follow this first field.

    The table below provides the bit layout of the uint32_vbr that describes the function.

    @@ -1060,8 +1131,7 @@ bit(0-3) - Encodes the calling convention number of the function. If this number is - zero, this field is followed by a vbr indicating the CC#. Otherwise, the + Encodes the calling convention number of the function. The CC number of the function is the value of this field minus one. @@ -1072,9 +1142,61 @@ Block in the bytecode file for the function. - bit(5-) + bit(5-30) Type slot number of type for the function. + + bit(31) + Indicates whether an extension word follows. + + + + +

    If bit(31) is set, an additional uint32_vbr word +follows with the following fields:

    + + + + + + + + + + + + + + + + + + + + + + + + +
    TypeDescription
    bit(0-4)The log-base-2 of the alignment for the function.
    bit(5-9)The top nibble of the calling convention.
    bit(10)If this bit is set, a SectionID follows this vbr.
    bit(11-31)Currently unassigned.
    + +

    If the SectionID bit is set above, the following field is included:

    + + + + + + + + + + +
    TypeDescription
    uint32_vbr + An optional section ID number, specifying the string + to use for the section of the function. This an index (+1) of an entry + into the SectionID llist in the Module Global + Info block. If this value is 0 or not present, the function has an + empty section string.
    @@ -1361,8 +1483,155 @@
    + + + + +
    +

    Instructions are written out one at a time as distinct units. Each +instruction +record contains at least an opcode and a type field, +and may contain a list of operands (whose +interpretation depends on the opcode). Based on the number of operands, the +instruction is encoded in a +dense format that tries to encoded each instruction into 32-bits if +possible.

    +
    + - + +
    +

    Instructions encode an opcode that identifies the kind of instruction. + Opcodes are an enumerated integer value. The specific values used depend on + the version of LLVM you're using. The opcode values are defined in the + + include/llvm/Instruction.def file. You should check there for the + most recent definitions. The table below provides the opcodes defined as of + the writing of this document. The table associates each opcode mnemonic with + its enumeration value and the bytecode and LLVM version numbers in which the + opcode was introduced.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    OpcodeNumberBytecode VersionLLVM Version
    Terminator Instructions
    Ret111.0
    Br211.0
    Switch311.0
    Invoke411.0
    Unwind511.0
    Unreachable611.4
    Binary Operators
    Add711.0
    Sub811.0
    Mul911.0
    Div1011.0
    Rem1111.0
    Logical Operators
    And1211.0
    Or1311.0
    Xor1411.0
    Binary Comparison Operators
    SetEQ1511.0
    SetNE1611.0
    SetLE1711.0
    SetGE1811.0
    SetLT1911.0
    SetGT2011.0
    Memory Operators
    Malloc2111.0
    Free2211.0
    Alloca2311.0
    Load2411.0
    Store2511.0
    GetElementPtr2611.0
    Other Operators
    PHI2711.0
    Cast2811.0
    Call2911.0
    Shl3011.0
    Shr3111.0
    VANext3211.0
    VAArg3311.0
    Select3421.2
    + Pseudo Instructions* +
    Invoke+CC 5651.5
    Invoke+FastCC5751.5
    Call+CC5851.5
    Call+FastCC+TailCall5951.5
    Call+FastCC6051.5
    Call+CCC+TailCall6151.5
    Load+Volatile6231.3
    Store+Volatile6331.3
    + +

    * Note: +These aren't really opcodes from an LLVM language perspective. They encode +information into other opcodes without reserving space for that information. +For example, opcode=63 is a Volatile Store. The opcode for this +instruction is 25 (Store) but we encode it as 63 to indicate that is a Volatile +Store. The same is done for the calling conventions and tail calls. +In each of these entries in range 56-63, the opcode is documented as the base +opcode (Invoke, Call, Store) plus some set of modifiers, as follows:

    +
    +
    CC
    +
    This means an arbitrary calling convention is specified + in a VBR that follows the opcode. This is used when the instruction cannot + be encoded with one of the more compact forms. +
    +
    FastCC
    +
    This indicates that the Call or Invoke is using the FastCC calling + convention.
    +
    CCC
    +
    This indicates that the Call or Invoke is using the native "C" calling + convention.
    +
    TailCall
    +
    This indicates that the Call has the 'tail' modifier.
    +
    +
    + + + + +
    +

    +Based on the instruction opcode and type, the bytecode format implicitly (to +save space) specifies the interpretation of the operand list. For most +instructions, the type of each operand is implicit from the type of the +instruction itself (e.g. the type of operands of a binary operator must match +the type of the instruction). As such, the bytecode format generally only +encodes the value number of the operand, not the type.

    + +

    In some cases, however, this is not sufficient. This section enumerates +those cases:

    + +
      +
    • getelementptr: the slot numbers for sequential type indexes are shifted up +two bits. This allows the low order bits will encode the type of index used, +as follows: 0=uint, 1=int, 2=ulong, 3=long.
    • +
    • cast: the result type number is encoded as the second operand.
    • +
    • alloca/malloc: If the allocation has an explicit alignment, the log2 of the + alignment is encoded as the second operand.
    • +
    • call: If the tail marker and calling convention cannot be encoded into the opcode of the call, it is passed as an + additional operand. The low bit of the operand is a flag indicating whether + the call is a tail call. The rest of the bits contain the calling + convention number (shifted left by one bit).
    • +
    +
    + + + +

    For brevity, instructions are written in one of four formats, depending on the number of operands to the instruction. Each @@ -1399,17 +1668,11 @@ uint32_vbr+ The slot number of the value(s) for the operand(s). - 1 + -Notes: -

      -
    1. Note that if the instruction is a getelementptr and the type of -the operand is a sequential type (array or pointer) then the slot -number is shifted up two bits and the low order bits will encode the -type of index used, as follows: 0=uint, 1=int, 2=ulong, 3=long.
    2. -
    +

    Instruction Format 1

    This format encodes the opcode, type and a single operand into a single uint32_vbr as follows:

    @@ -1428,7 +1691,7 @@ 2-7 - opcode + opcode Specifies the opcode of the instruction. Note that the maximum opcode value is 63. @@ -1465,7 +1728,7 @@ 2-7 - opcode + opcode Specifies the opcode of the instruction. Note that the maximum opcode value is 63. @@ -1507,7 +1770,7 @@ 2-7 - opcode + opcode Specifies the opcode of the instruction. Note that the maximum opcode value is 63. @@ -1540,105 +1803,6 @@
    - -
    -

    Instructions encode an opcode that identifies the kind of instruction. - Opcodes are an enumerated integer value. The specific values used depend on - the version of LLVM you're using. The opcode values are defined in the - - include/llvm/Instruction.def file. You should check there for the - most recent definitions. The table below provides the opcodes defined as of - the writing of this document. The table associates each opcode mnemonic with - its enumeration value and the bytecode and LLVM version numbers in which the - opcode was introduced.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    OpcodeNumberBytecode VersionLLVM Version
    Terminator Instructions
    Ret111.0
    Br211.0
    Switch311.0
    Invoke411.0
    Unwind511.0
    Unreachable611.4
    Binary Operators
    Add711.0
    Sub811.0
    Mul911.0
    Div1011.0
    Rem1111.0
    Logical Operators
    And1211.0
    Or1311.0
    Xor1411.0
    Binary Comparison Operators
    SetEQ1511.0
    SetNE1611.0
    SetLE1711.0
    SetGE1811.0
    SetLT1911.0
    SetGT2011.0
    Memory Operators
    Malloc2111.0
    Free2211.0
    Alloca2311.0
    Load2411.0
    Store2511.0
    GetElementPtr2611.0
    Other Operators
    PHI2711.0
    Cast2811.0
    Call2911.0
    Shl3011.0
    Shr3111.0
    VANext3211.0
    VAArg3311.0
    Select3421.2
    - Pseudo Instructions* -
    Invoke+CC 5651.5
    Invoke+FastCC5751.5
    Call+CC5851.5
    Call+FastCC+TailCall5951.5
    Call+FastCC6051.5
    Call+CCC+TailCall6151.5
    Load+Volatile6231.3
    Store+Volatile6331.3
    -
    - -

    * Note: -These aren't really opcodes from an LLVM language prespeective. They encode -information into other opcodes without reserving space for that information. -For example, opcode=63 is a Volatile Store. The opcode for this -instruction is 25 (Store) but we encode it as 63 to indicate that is a Volatile -Store. The same is done for the calling conventions and tail calls. -In each of these entries in range 56-63, the opcode is documented as the base -opcode (Invoke, Call, Store) plus some set of modifiers, as follows:

    -
    -
    CC
    -
    This means an arbitrary calling convention is specified - in a VBR that follows the opcode. This is used when the instruction cannot - be encoded with one of the more compact forms. -
    -
    FastCC
    -
    This indicates that the Call or Invoke is using the FastCC calling - convention.
    -
    CCC
    -
    This indicates that the Call or Invoke is using the native "C" calling - convention.
    -
    TailCall
    -
    This indicates that the Call has the 'tail' modifier.
    -
    - -

    A symbol table can be put out in conjunction with a module or a function. A @@ -1935,7 +2099,7 @@ Reid Spencer and Chris Lattner
    The LLVM Compiler Infrastructure
    -Last modified: $Date: 2005/05/14 01:30:15 $ +Last modified: $Date: 2005/11/16 18:31:07 $ Index: llvm/docs/CFEBuildInstrs.html diff -u llvm/docs/CFEBuildInstrs.html:1.53 llvm/docs/CFEBuildInstrs.html:1.53.2.1 --- llvm/docs/CFEBuildInstrs.html:1.53 Tue Sep 20 22:56:26 2005 +++ llvm/docs/CFEBuildInstrs.html Wed Nov 16 12:31:07 2005 @@ -68,9 +68,10 @@ and Settings" directory). We welcome patches to fix this issue.

    It has been found that the GCC 3.3.3 compiler provided with recent Cygwin -versions is incapable of compiling the LLVM CFE correctly. If your Cygwin +versions is incapable of compiling the LLVM GCC front-end correctly. If your +Cygwin installation includes GCC 3.3.3, we strongly recommend that you download -GCC 3.4.3, build it separately, and use it for compiling LLVM CFE. This has been +GCC 3.4.3, build it separately, and use it for compiling the LLVM GCC front-end. This has been shown to work correctly.

    Some versions of Cygwin utilize an experimental version of GNU binutils that will cause the GNU ld linker to fail an assertion when linking @@ -356,7 +357,7 @@ Brian Gaeke
    LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/09/21 03:56:26 $ + Last modified: $Date: 2005/11/16 18:31:07 $ Index: llvm/docs/CodeGenerator.html diff -u llvm/docs/CodeGenerator.html:1.27 llvm/docs/CodeGenerator.html:1.27.2.1 --- llvm/docs/CodeGenerator.html:1.27 Mon Oct 17 10:19:24 2005 +++ llvm/docs/CodeGenerator.html Wed Nov 16 12:31:07 2005 @@ -1117,7 +1117,7 @@ Selection DAG is destroyed.

    -

    Note that this phase is logically seperate from the instruction selection +

    Note that this phase is logically separate from the instruction selection phase, but is tied to it closely in the code because it operates on SelectionDAGs.

    @@ -1297,7 +1297,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/10/17 15:19:24 $ + Last modified: $Date: 2005/11/16 18:31:07 $ Index: llvm/docs/CommandLine.html diff -u llvm/docs/CommandLine.html:1.38 llvm/docs/CommandLine.html:1.38.2.1 --- llvm/docs/CommandLine.html:1.38 Fri Aug 26 04:25:54 2005 +++ llvm/docs/CommandLine.html Wed Nov 16 12:31:07 2005 @@ -195,7 +195,7 @@ program:

    -  #include "Support/CommandLine.h"
    +  #include "llvm/Support/CommandLine.h"
     

    Additionally, you need to add this as the first line of your main @@ -1900,7 +1900,7 @@ Chris Lattner
    LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/08/26 09:25:54 $ + Last modified: $Date: 2005/11/16 18:31:07 $ Index: llvm/docs/ExtendingLLVM.html diff -u llvm/docs/ExtendingLLVM.html:1.18 llvm/docs/ExtendingLLVM.html:1.18.4.1 --- llvm/docs/ExtendingLLVM.html:1.18 Tue May 10 22:53:53 2005 +++ llvm/docs/ExtendingLLVM.html Wed Nov 16 12:31:07 2005 @@ -266,7 +266,7 @@ add enum for the new type; add a forward declaration of the type also -

  • llvm/include/llvm/DerivedType.h: +
  • llvm/include/llvm/DerivedTypes.h: add new class to represent new class in the hierarchy; add forward declaration to the TypeMap value type
  • @@ -322,7 +322,7 @@ The LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/05/11 03:53:53 $ + Last modified: $Date: 2005/11/16 18:31:07 $ Index: llvm/docs/GettingStarted.html diff -u llvm/docs/GettingStarted.html:1.120 llvm/docs/GettingStarted.html:1.120.2.1 --- llvm/docs/GettingStarted.html:1.120 Mon Sep 5 23:07:15 2005 +++ llvm/docs/GettingStarted.html Wed Nov 16 12:31:07 2005 @@ -362,7 +362,7 @@ Bison - 1.35 + 1.28, 1.35, 1.75, or 2.0 (not 1.85) YACC compiler @@ -661,6 +661,7 @@ labels:

      +
    • Release 1.6: RELEASE_16
    • Release 1.5: RELEASE_15
    • Release 1.4: RELEASE_14
    • Release 1.3: RELEASE_13
    • @@ -1540,7 +1541,7 @@ Chris Lattner
      Reid Spencer
      The LLVM Compiler Infrastructure
      - Last modified: $Date: 2005/09/06 04:07:15 $ + Last modified: $Date: 2005/11/16 18:31:07 $ Index: llvm/docs/GettingStartedVS.html diff -u llvm/docs/GettingStartedVS.html:1.4 llvm/docs/GettingStartedVS.html:1.4.4.1 --- llvm/docs/GettingStartedVS.html:1.4 Mon Mar 7 21:56:50 2005 +++ llvm/docs/GettingStartedVS.html Wed Nov 16 12:31:07 2005 @@ -170,15 +170,10 @@ beta, there are no guarantees and there is no support for it at this time. It has been reported that VC++ Express also works.

      -

      You will also need several open source packages: bison, flex, and sed. - These must be installed in llvm/win32/tools. These can be found at - http://gnuwin32.sourceforge.net - or - http://unxutils.sourceforge.net. - Bison prefers that m4 be in the path. You must add it to the Visual Studio - configuration under the menu Options -> Projects -> VC++ Directories. - Alternatively, you can set the environment variable M4 to point to - m4 executable.

      +

      If you plan to modify any .y or .l files, you will need to have bison + and/or flex installed where Visual Studio can find them. Otherwise, you do + not need them and the pre-generated files that come with the source tree + will be used.

    @@ -279,28 +274,26 @@

    Note: while you cannot do this step on Windows, you can do it on a Unix system and transfer hello.bc to Windows.

    -
  • Run the program. To make sure the program ran, execute the - following command:

    +
  • Run the program using the just-in-time compiler:

    % lli hello.bc

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

    -

    % llvm-dis < hello.bc | less

  • +

    % llvm-dis < hello.bc | more

    -

  • Compile the program to native assembly using the LLC code - generator:

    +
  • Compile the program to C using the LLC code generator:

    -

    % llc hello.bc -o hello.s

    +

    % llc -march=c hello.bc

  • -
  • Assemble the native assembly language file into a program:

    +
  • Compile to binary using Microsoft C:

    -

    Not currently possible, but eventually will use NASMW.

    +

    % cl hello.cbe.c

  • Execute the native code program:

    -

    % ./hello.native

  • +

    % hello.cbe.exe

    @@ -354,7 +347,7 @@ Jeff Cohen
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/03/08 03:56:50 $ + Last modified: $Date: 2005/11/16 18:31:07 $ Index: llvm/docs/LangRef.html diff -u llvm/docs/LangRef.html:1.112.2.1 llvm/docs/LangRef.html:1.112.2.2 --- llvm/docs/LangRef.html:1.112.2.1 Tue Oct 18 14:21:55 2005 +++ llvm/docs/LangRef.html Wed Nov 16 12:31:07 2005 @@ -138,6 +138,7 @@
  • 'llvm.frameaddress' Intrinsic
  • 'llvm.prefetch' Intrinsic
  • 'llvm.pcmarker' Intrinsic
  • +
  • llvm.readcyclecounter' Intrinsic
  • Operating System Intrinsics @@ -505,12 +506,14 @@

    Global variables define regions of memory allocated at compilation time -instead of run-time. Global variables may optionally be initialized. A -variable may be defined as a global "constant", which indicates that the +instead of run-time. Global variables may optionally be initialized, may have +an explicit section to be placed in, and may +have an optional explicit alignment specified. A +variable may be defined as a global "constant," which indicates that the contents of the variable will never be modified (enabling better optimization, allowing the global data to be placed in the read-only section of an executable, etc). Note that variables that need runtime initialization -cannot be marked "constant", as there is a store to the variable.

    +cannot be marked "constant" as there is a store to the variable.

    LLVM explicitly allows declarations of global variables to be marked @@ -527,6 +530,15 @@ describe a region of memory, and all memory objects in LLVM are accessed through pointers.

    +

    LLVM allows an explicit section to be specified for globals. If the target +supports it, it will emit globals to the section specified.

    + +

    An explicit alignment may be specified for a global. If not present, or if +the alignment is set to zero, the alignment of the global is set by the target +to whatever it feels convenient. If an explicit alignment is specified, the +global is forced to have at least that much alignment. All alignments must be +a power of 2.

    +
    @@ -539,11 +551,12 @@

    LLVM function definitions consist of an optional linkage type, an optional calling convention, a return -type, a function name, a (possibly empty) argument list, an opening curly brace, +type, a function name, a (possibly empty) argument list, an optional section, +an optional alignment, an opening curly brace, a list of basic blocks, and a closing curly brace. LLVM function declarations are defined with the "declare" keyword, an optional calling convention, a return type, a function name, and -a possibly empty list of arguments.

    +href="#callingconv">calling convention, a return type, a function name, +a possibly empty list of arguments, and an optional alignment.

    A function definition contains a list of basic blocks, forming the CFG for the function. Each basic block may optionally start with a label (giving the @@ -562,6 +575,15 @@ considered different functions, and LLVM will resolve references to each appropriately.

    +

    LLVM allows an explicit section to be specified for functions. If the target +supports it, it will emit functions to the section specified.

    + +

    An explicit alignment may be specified for a function. If not present, or if +the alignment is set to zero, the alignment of the function is set by the target +to whatever it feels convenient. If an explicit alignment is specified, the +function is forced to have at least that much alignment. All alignments must be +a power of 2.

    + @@ -732,8 +754,8 @@ -

    Note that 'variable sized arrays' can be implemented in LLVM With a zero -length array. Normally accesses past the end of an array are undefined in +

    Note that 'variable sized arrays' can be implemented in LLVM with a zero +length array. Normally, accesses past the end of an array are undefined in LLVM (e.g. it is illegal to access the 5th element of a 3 element array). As a special case, however, zero length arrays are recognized to be variable length. This allows implementation of 'pascal style arrays' with the LLVM @@ -755,7 +777,7 @@

    Syntax:
      <returntype> (<parameter list>)
    -

    Where '<parameter list>' is a comma-separated list of type +

    ...where '<parameter list>' is a comma-separated list of type specifiers. Optionally, the parameter list may include a type ..., which indicates that the function takes a variable number of arguments. Variable argument functions can access their arguments with the The string 'zeroinitializer' can be used to zero initialize a value to zero of any type, including scalar and aggregate types. This is often used to avoid having to print large zero initializers (e.g. for - large arrays), and is always exactly equivalent to using explicit zero + large arrays) and is always exactly equivalent to using explicit zero initializers. @@ -1540,7 +1562,7 @@

    This returns the remainder of a division (where the result has the same sign as the divisor), not the modulus (where the result has the same sign as the dividend) of a value. For more -information about the difference, see: The Math Forum.

    Example:
    @@ -1868,98 +1890,157 @@ <result> = shr sbyte -2, ubyte 1 ; yields {sbyte}:result = -1 + - + +
    +

    A key design point of an SSA-based representation is how it represents memory. In LLVM, no memory locations are in SSA form, which makes things very simple. This section describes how to read, write, allocate, and free memory in LLVM.

    +
    + - + +
    +
    Syntax:
    -
      <result> = malloc <type>, uint <NumElements>     ; yields {type*}:result
    -  <result> = malloc <type>                         ; yields {type*}:result
    +
    +
    +  <result> = malloc <type>[, uint <NumElements>][, align <alignment>]     ; yields {type*}:result
     
    +
    Overview:
    +

    The 'malloc' instruction allocates memory from the system heap and returns a pointer to it.

    +
    Arguments:
    -

    The 'malloc' instruction allocates sizeof(<type>)*NumElements + +

    The 'malloc' instruction allocates +sizeof(<type>)*NumElements bytes of memory from the operating system and returns a pointer of the -appropriate type to the program. The second form of the instruction is -a shorter version of the first instruction that defaults to allocating -one element.

    +appropriate type to the program. If "NumElements" is specified, it is the +number of elements allocated. If an alignment is specified, the value result +of the allocation is guaranteed to be aligned to at least that boundary. If +not specified, or if zero, the target can choose to align the allocation on any +convenient boundary.

    +

    'type' must be a sized type.

    +
    Semantics:
    +

    Memory is allocated using the system "malloc" function, and a pointer is returned.

    +
    Example:
    -
      %array  = malloc [4 x ubyte ]                    ; yields {[%4 x ubyte]*}:array
     
    -  %size   = add uint 2, 2                          ; yields {uint}:size = uint 4
    +
    +  %array  = malloc [4 x ubyte ]                    ; yields {[%4 x ubyte]*}:array
    +
    +  %size   = add uint 2, 2                          ; yields {uint}:size = uint 4
       %array1 = malloc ubyte, uint 4                   ; yields {ubyte*}:array1
       %array2 = malloc [12 x ubyte], uint %size        ; yields {[12 x ubyte]*}:array2
    +  %array3 = malloc int, uint 4, align 1024         ; yields {int*}:array3
    +  %array4 = malloc int, align 1024                 ; yields {int*}:array4
     
    + - + +
    +
    Syntax:
    -
      free <type> <value>                              ; yields {void}
    +
    +
    +  free <type> <value>                              ; yields {void}
     
    +
    Overview:
    +

    The 'free' instruction returns memory back to the unused memory heap to be reallocated in the future.

    -

    +
    Arguments:
    +

    'value' shall be a pointer value that points to a value that was allocated with the 'malloc' instruction.

    +
    Semantics:
    +

    Access to the memory pointed to by the pointer is no longer defined after this instruction executes.

    +
    Example:
    -
      %array  = malloc [4 x ubyte]                    ; yields {[4 x ubyte]*}:array
    +
    +
    +  %array  = malloc [4 x ubyte]                    ; yields {[4 x ubyte]*}:array
                 free   [4 x ubyte]* %array
     
    + - + +
    +
    Syntax:
    -
      <result> = alloca <type>, uint <NumElements>  ; yields {type*}:result
    -  <result> = alloca <type>                      ; yields {type*}:result
    +
    +
    +  <result> = alloca <type>[, uint <NumElements>][, align <alignment>]     ; yields {type*}:result
     
    +
    Overview:
    +

    The 'alloca' instruction allocates memory on the current stack frame of the procedure that is live until the current function returns to its caller.

    +
    Arguments:
    +

    The 'alloca' instruction allocates sizeof(<type>)*NumElements bytes of memory on the runtime stack, returning a pointer of the -appropriate type to the program. The second form of the instruction is -a shorter version of the first that defaults to allocating one element.

    +appropriate type to the program. If "NumElements" is specified, it is the +number of elements allocated. If an alignment is specified, the value result +of the allocation is guaranteed to be aligned to at least that boundary. If +not specified, or if zero, the target can choose to align the allocation on any +convenient boundary.

    +

    'type' may be any sized type.

    +
    Semantics:
    +

    Memory is allocated; a pointer is returned. 'alloca'd memory is automatically released when the function returns. The 'alloca' instruction is commonly used to represent automatic variables that must have an address available. When the function returns (either with the ret or unwind instructions), the memory is reclaimed.

    +
    Example:
    -
      %ptr = alloca int                              ; yields {int*}:ptr
    +
    +
    +  %ptr = alloca int                              ; yields {int*}:ptr
       %ptr = alloca int, uint 4                      ; yields {int*}:ptr
    +  %ptr = alloca int, uint 4, align 1024          ; yields {int*}:ptr
    +  %ptr = alloca int, align 1024                  ; yields {int*}:ptr
     
    + @@ -2955,7 +3036,7 @@

    This instruction takes a va_list* value and the type of the argument. It returns a value of the specified argument type and -increments the va_list to poin to the next argument. Again, the +increments the va_list to point to the next argument. Again, the actual type of va_list is target specific.

    Semantics:
    @@ -3422,8 +3503,8 @@ (PC) in a region of code to simulators and other tools. The method is target specific, but it is expected that the marker will use exported symbols to transmit the PC of the marker. -The marker makes no guaranties that it will remain with any specific instruction -after optimizations. It is possible that the presense of a marker will inhibit +The marker makes no guarantees that it will remain with any specific instruction +after optimizations. It is possible that the presence of a marker will inhibit optimizations. The intended use is to be inserted after optmizations to allow correlations of simulation runs.

    @@ -3443,6 +3524,39 @@ + + + +
    + +
    Syntax:
    +
    +  declare ulong %llvm.readcyclecounter( )
    +
    + +
    Overview:
    + + +

    +The 'llvm.readcyclecounter' intrinsic provides access to the cycle +counter register (or similar low latency, high accuracy clocks) on those targets +that support it. On X86, it should map to RDTSC. On Alpha, it should map to RPCC. +As the backing counters overflow quickly (on the order of 9 seconds on alpha), this +should only be used for small timings. +

    + +
    Semantics:
    + +

    +When directly supported, reading the cycle counter should not modify any memory. +Implementations are allowed to either return a application specific value or a +system wide value. On backends without support, this is lowered to a constant 0. +

    + +
    +
    @@ -4020,7 +4134,8 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/10/18 19:21:55 $ + + Last modified: $Date: 2005/11/16 18:31:07 $ Index: llvm/docs/MakefileGuide.html diff -u llvm/docs/MakefileGuide.html:1.25 llvm/docs/MakefileGuide.html:1.25.4.1 --- llvm/docs/MakefileGuide.html:1.25 Tue May 10 17:06:14 2005 +++ llvm/docs/MakefileGuide.html Wed Nov 16 12:31:08 2005 @@ -552,7 +552,7 @@

    This utility target, only available when $(PROJ_OBJ_ROOT) is not the same as $(PROJ_SRC_ROOT), will completely clean the - $(PROJ_OBJ_ROOT) directoy by removing its content entirely and + $(PROJ_OBJ_ROOT) directory by removing its content entirely and reconfiguring the directory. This returns the $(PROJ_OBJ_ROOT) directory to a completely fresh state. All content in the directory except configured files and top-level makefiles will be lost.

    @@ -999,7 +999,7 @@ Reid Spencer
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/05/10 22:06:14 $ + Last modified: $Date: 2005/11/16 18:31:08 $ Index: llvm/docs/ProgrammersManual.html diff -u llvm/docs/ProgrammersManual.html:1.87 llvm/docs/ProgrammersManual.html:1.87.2.1 --- llvm/docs/ProgrammersManual.html:1.87 Sun Oct 16 20:36:23 2005 +++ llvm/docs/ProgrammersManual.html Wed Nov 16 12:31:08 2005 @@ -28,7 +28,7 @@
    • The isa<>, cast<> and dyn_cast<> templates
    • -
    • The DEBUG() macro & -debug +
    • The DEBUG() macro and -debug option
      • Fine grained debug info with DEBUG_TYPE @@ -264,7 +264,8 @@
        @@ -317,44 +318,45 @@ checks to see if the operand is of the specified type, and if so, returns a pointer to it (this operator does not work with references). If the operand is not of the correct type, a null pointer is returned. Thus, this works very - much like the dynamic_cast operator in C++, and should be used in the - same circumstances. Typically, the dyn_cast<> operator is used - in an if statement or some other flow control statement like this: + much like the dynamic_cast<> operator in C++, and should be + used in the same circumstances. Typically, the dyn_cast<> + operator is used in an if statement or some other flow control + statement like this: -
        +  
              if (AllocationInst *AI = dyn_cast<AllocationInst>(Val)) {
                ...
              }
        -   
        +
        -

        This form of the if statement effectively combines together a - call to isa<> and a call to cast<> into one - statement, which is very convenient.

        - -

        Note that the dyn_cast<> operator, like C++'s - dynamic_cast or Java's instanceof operator, can be abused. - In particular you should not use big chained if/then/else blocks to - check for lots of different variants of classes. If you find yourself - wanting to do this, it is much cleaner and more efficient to use the - InstVisitor class to dispatch over the instruction type directly.

        +

        This form of the if statement effectively combines together a call + to isa<> and a call to cast<> into one + statement, which is very convenient.

        + +

        Note that the dyn_cast<> operator, like C++'s + dynamic_cast<> or Java's instanceof operator, can be + abused. In particular, you should not use big chained if/then/else + blocks to check for lots of different variants of classes. If you find + yourself wanting to do this, it is much cleaner and more efficient to use the + InstVisitor class to dispatch over the instruction type directly.

        - + -
        cast_or_null<>:
        - -
        The cast_or_null<> operator works just like the - cast<> operator, except that it allows for a null pointer as - an argument (which it then propagates). This can sometimes be useful, - allowing you to combine several null checks into one.
        - -
        dyn_cast_or_null<>:
        - -
        The dyn_cast_or_null<> operator works just like the - dyn_cast<> operator, except that it allows for a null pointer - as an argument (which it then propagates). This can sometimes be useful, - allowing you to combine several null checks into one.
        +
        cast_or_null<>:
        + +
        The cast_or_null<> operator works just like the + cast<> operator, except that it allows for a null pointer as an + argument (which it then propagates). This can sometimes be useful, allowing + you to combine several null checks into one.
        + +
        dyn_cast_or_null<>:
        + +
        The dyn_cast_or_null<> operator works just like the + dyn_cast<> operator, except that it allows for a null pointer + as an argument (which it then propagates). This can sometimes be useful, + allowing you to combine several null checks into one.
        - +

        These five templates can be used with any classes, whether they have a v-table or not. To add support for these templates, you simply need to add @@ -366,7 +368,7 @@

        @@ -2275,7 +2277,7 @@ Dinakar Dhurjati and Chris Lattner
        The LLVM Compiler Infrastructure
        - Last modified: $Date: 2005/10/17 01:36:23 $ + Last modified: $Date: 2005/11/16 18:31:08 $ Index: llvm/docs/Projects.html diff -u llvm/docs/Projects.html:1.18 llvm/docs/Projects.html:1.18.4.1 --- llvm/docs/Projects.html:1.18 Sun Feb 27 19:10:48 2005 +++ llvm/docs/Projects.html Wed Nov 16 12:31:08 2005 @@ -87,6 +87,12 @@ choosing. You can place it anywhere you like. Rename the directory to match the name of your project.
      • +
      • +If you downloaded LLVM using CVS, remove all the directories named CVS (and all +the files therein) from your project's new source tree. This will keep CVS +from thinking that your project is inside llvm/projects/sample. +
      • +
      • Add your source code and Makefiles to your source tree.
      • If you want your project to be configured with the configure script @@ -447,7 +453,7 @@ John Criswell
        The LLVM Compiler Infrastructure
        - Last modified: $Date: 2005/02/28 01:10:48 $ + Last modified: $Date: 2005/11/16 18:31:08 $ Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.333 llvm/docs/ReleaseNotes.html:1.333.2.1 --- llvm/docs/ReleaseNotes.html:1.333 Tue Jul 12 11:36:24 2005 +++ llvm/docs/ReleaseNotes.html Wed Nov 16 12:31:08 2005 @@ -4,11 +4,11 @@ - LLVM 1.6 Release Notes + LLVM 1.7cvs Release Notes -
        LLVM 1.6 Release Notes
        +
        LLVM 1.7 Release Notes
        1. Introduction
        2. @@ -20,7 +20,7 @@
        -

        Written by the LLVM Team

        +

        Written by the LLVM Team

        @@ -32,15 +32,15 @@

        This document contains the release notes for the LLVM compiler -infrastructure, release 1.6. Here we describe the status of LLVM, including any +infrastructure, release 1.7. Here we describe the status of LLVM, including any known problems and major improvements from the previous release. The most up-to-date version of this document can be found on the LLVM 1.6 web site. If you are +href="http://llvm.org/releases/">LLVM releases web site. If you are not reading this on the LLVM web pages, you should probably go there because this document may be updated after the release.

        For more information about LLVM, including information about the latest -release, please check out the main LLVM +release, please check out the main LLVM web site. If you have questions or comments, the LLVM developer's mailing list is a good place to send them.

        @@ -48,7 +48,7 @@

        Note that if you are reading this file from CVS or the main LLVM web page, this document applies to the next release, not the current one. To see the release notes for the current or previous releases, see the releases page.

        +href="http://llvm.org/releases/">releases page.

        @@ -60,53 +60,20 @@
        -

        This is the seventh public release of the LLVM Compiler Infrastructure.

        +

        This is the seventh public release of the LLVM Compiler Infrastructure. This +release incorporates a large number of enhancements and additions (primarily in +the code generator), which combine to improve the quality of the code generated +by LLVM by up to 30% in some cases. This release is also the first release to +have first-class support for Mac OS X: all of the major bugs have been shaken +out and it is now as well supported as Linux on X86.

        -

        LLVM 1.6 is known to correctly compile a wide range of C and C++ programs, -includes bug fixes for those problems found since the 1.5 release, and includes -a large number of new features and enhancements, described below.

        - -
        - - - - -
        -

        - See LLVM 1.5 Release Notes -

        -
          -
        1. The JIT now uses mutexes to protect its internal data structures. This - allows multi-threaded programs to be run from the JIT or interpreter without - corruption of the internal data structures. See - PR418 and - PR540 for the details. -
        2. -
        - - - - - - -
        @@ -124,7 +91,7 @@
      • Sun UltraSPARC workstations running Solaris 8.
      • Intel and AMD machines running on Win32 with the Cygwin libraries (limited support is available for native builds with Visual C++).
      • -
      • PowerPC-based Mac OS X systems, running 10.2 and above.
      • +
      • PowerPC and X86-based Mac OS X systems, running 10.2 and above.
      • Alpha-based machines running Debian GNU/Linux.
      • Itanium-based machines running Linux and HP-UX.
      @@ -148,7 +115,7 @@

      This section contains all known problems with the LLVM system, listed by component. As new problems are discovered, they will be added to these sections. If you run into a problem, please check the LLVM bug database and submit a bug if +href="http://llvm.org/bugs/">LLVM bug database and submit a bug if there isn't already one.

    @@ -168,18 +135,30 @@
    • The following passes are incomplete or buggy, and may be removed in future - releases: -cee, -branch-combine, -instloops, -paths, -pre
    • + releases: -cee, -pre
    • The llvm-db tool is in a very early stage of development, but can be used to step through programs and inspect the stack.
    • -
    • The "iterative scan" register allocator (enabled with - -regalloc=iterativescan) is not stable.
    • -
    • The SparcV8, Alpha, and IA64 code generators are experimental.
    • +
    • The SparcV8 and IA64 code generators are experimental.
    • +
    • The Alpha JIT is experimental.
    + +
    + + +
    + + + + @@ -188,10 +167,6 @@ @@ -215,7 +190,7 @@
  • Initialization of global union variables can only be done with the largest union member.
  • +href="http://llvm.org/PR162">with the largest union member. @@ -440,7 +415,7 @@ (for example, GCC requires the -fno-strict-aliasing option). This problem probably cannot be fixed. -
  • Zero arg vararg functions are not +
  • Zero arg vararg functions are not supported. This should not affect LLVM produced by the C or C++ frontends.
  • @@ -456,7 +431,8 @@ @@ -482,7 +458,7 @@
    @@ -500,10 +476,6 @@
  • On 21164s, some rare FP arithmetic sequences which may trap do not have the appropriate nops inserted to ensure restartability.
  • -
  • Defining vararg functions is not supported (but calling them is ok).
  • - -
  • Due to the vararg problems, C++ exceptions do not work. Small changes are required to the CFE (which break correctness in the exception handler) to compile the exception handling library (and thus the C++ standard library).
  • -
    @@ -522,7 +494,7 @@ speaking this is not a bug in the IA64 back-end; it will also be encountered when building C++ programs using the C back-end.) -
  • The C++ front-end does not use IA64 +
  • The C++ front-end does not use IA64 ABI compliant layout of v-tables. In particular, it just stores function pointers instead of function descriptors in the vtable. This bug prevents mixing C++ code compiled with LLVM with C++ objects compiled by other C++ @@ -547,12 +519,8 @@
    • Many features are still missing (e.g. support for 64-bit integer -arithmetic).
    • - -
    • This backend needs to be updated to use the SelectionDAG instruction -selection framework.
    • +arithmetic). This back-end is in pre-beta state.
    - @@ -564,16 +532,16 @@

    A wide variety of additional information is available on the LLVM web page, including documentation and publications describing algorithms and +href="http://llvm.org">LLVM web page, including documentation and publications describing algorithms and components implemented in LLVM. The web page also contains versions of the API documentation which is up-to-date with the CVS version of the source code. You can access versions of these documents specific to this release by going into the "llvm/doc/" directory in the LLVM tree.

    If you have any questions or comments about LLVM, please feel free to contact -us via the mailing +us via the mailing lists.

    @@ -587,8 +555,8 @@ Valid HTML 4.01! - The LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/07/12 16:36:24 $ + The LLVM Compiler Infrastructure
    + Last modified: $Date: 2005/11/16 18:31:08 $ Index: llvm/docs/TableGenFundamentals.html diff -u llvm/docs/TableGenFundamentals.html:1.13 llvm/docs/TableGenFundamentals.html:1.13.2.1 --- llvm/docs/TableGenFundamentals.html:1.13 Thu Sep 8 13:47:21 2005 +++ llvm/docs/TableGenFundamentals.html Wed Nov 16 12:31:08 2005 @@ -337,7 +337,7 @@ information that TableGen collects. Records are defined with a def or class keyword, the record name, and an optional list of "template arguments". If the record has superclasses, -they are specified as a comma seperated list that starts with a colon character +they are specified as a comma separated list that starts with a colon character (":"). If value definitions or let expressions are needed for the class, they are enclosed in curly braces ("{}"); otherwise, the record ends with a semicolon. Here is a simple TableGen @@ -517,7 +517,7 @@ File-scope let expressions are really just another way that TableGen allows the end-user to factor out commonality from the records.

    -

    File-scope "let" expressions take a comma-seperated list of bindings to +

    File-scope "let" expressions take a comma-separated list of bindings to apply, and one of more records to bind the values in. Here are some examples:

    @@ -560,7 +560,7 @@ Chris Lattner
    LLVM Compiler Infrastructure
    - Last modified: $Date: 2005/09/08 18:47:21 $ + Last modified: $Date: 2005/11/16 18:31:08 $ From bocchino at cs.uiuc.edu Wed Nov 16 12:31:24 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:31:24 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/include/llvm/ADT/hash_map.in hash_set.in iterator.in Message-ID: <200511161831.MAA20630@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/ADT: hash_map.in updated: 1.9 -> 1.9.2.1 hash_set.in updated: 1.6 -> 1.6.2.1 iterator.in updated: 1.3 -> 1.3.6.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+27 -7) hash_map.in | 18 +++++++++++++----- hash_set.in | 10 ++++++++-- iterator.in | 6 ++++++ 3 files changed, 27 insertions(+), 7 deletions(-) Index: llvm/include/llvm/ADT/hash_map.in diff -u llvm/include/llvm/ADT/hash_map.in:1.9 llvm/include/llvm/ADT/hash_map.in:1.9.2.1 --- llvm/include/llvm/ADT/hash_map.in:1.9 Wed Aug 24 09:03:07 2005 +++ llvm/include/llvm/ADT/hash_map.in Wed Nov 16 12:31:13 2005 @@ -24,7 +24,7 @@ // 3.0.4 std ext/hash_map // 3.1 __gnu_cxx ext/hash_map // HP aCC6 std stdex/rw/hashm*ap.h -// +// MS VC++ stdext hash_map #undef HAVE_GNU_EXT_HASH_MAP #undef HAVE_STD_EXT_HASH_MAP @@ -63,6 +63,14 @@ # define HASH_NAMESPACE std # endif +// Support Microsoft VC++. +#elif defined(_MSC_VER) +# include +# ifndef HASH_NAMESPACE +# define HASH_NAMESPACE stdext + using std::_Distance; +# endif + // Give a warning if we couldn't find it, instead of (or in addition to) // randomly doing something dumb. #else @@ -100,10 +108,6 @@ } // end HASH_NAMESPACE; #endif -using HASH_NAMESPACE::hash_map; -using HASH_NAMESPACE::hash_multimap; -using HASH_NAMESPACE::hash; - // Include vector because ext/hash_map includes stl_vector.h and leaves // out specializations like stl_bvector.h, causing link conflicts. #include @@ -137,6 +141,10 @@ #endif +using HASH_NAMESPACE::hash_map; +using HASH_NAMESPACE::hash_multimap; +using HASH_NAMESPACE::hash; + #include "llvm/ADT/HashExtras.h" #endif Index: llvm/include/llvm/ADT/hash_set.in diff -u llvm/include/llvm/ADT/hash_set.in:1.6 llvm/include/llvm/ADT/hash_set.in:1.6.2.1 --- llvm/include/llvm/ADT/hash_set.in:1.6 Wed Aug 24 05:57:30 2005 +++ llvm/include/llvm/ADT/hash_set.in Wed Nov 16 12:31:13 2005 @@ -25,7 +25,7 @@ // 3.0.4 std ext/hash_set // 3.1 __gnu_cxx ext/hash_set // HP aCC6 std stdex/rw/hashset.h -// +// MS VC++ stdext hash_set #undef HAVE_GNU_EXT_HASH_SET #undef HAVE_STD_EXT_HASH_SET @@ -64,6 +64,13 @@ # define HASH_NAMESPACE std # endif +// Support Microsoft VC++. +#elif defined(_MSC_VER) +# include +# ifndef HASH_NAMESPACE +# define HASH_NAMESPACE stdext +# endif + // Give a warning if we couldn't find it, instead of (or in addition to) // randomly doing something dumb. #else @@ -94,7 +101,6 @@ #endif using HASH_NAMESPACE::hash_set; -using HASH_NAMESPACE::hash; // Include vector because ext/hash_set includes stl_vector.h and leaves // out specializations like stl_bvector.h, causing link conflicts. Index: llvm/include/llvm/ADT/iterator.in diff -u llvm/include/llvm/ADT/iterator.in:1.3 llvm/include/llvm/ADT/iterator.in:1.3.6.1 --- llvm/include/llvm/ADT/iterator.in:1.3 Fri Sep 24 16:19:05 2004 +++ llvm/include/llvm/ADT/iterator.in Wed Nov 16 12:31:13 2005 @@ -34,6 +34,12 @@ #undef HAVE_STD_ITERATOR #undef HAVE_FWD_ITERATOR +#ifdef _MSC_VER +# define HAVE_BI_ITERATOR 0 +# define HAVE_STD_ITERATOR 1 +# define HAVE_FWD_ITERATOR 0 +#endif + #if !HAVE_BI_ITERATOR # if HAVE_STD_ITERATOR /// If the bidirectional iterator is not defined, we attempt to define it in From bocchino at cs.uiuc.edu Wed Nov 16 12:31:57 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:31:57 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/include/llvm/Analysis/ConstantFolding.h Expressions.h FindUnsafePointerTypes.h LinkAllAnalyses.h Passes.h Message-ID: <200511161831.MAA20656@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: ConstantFolding.h added (r1.1.4.2) Expressions.h (r1.12) removed FindUnsafePointerTypes.h (r1.18) removed LinkAllAnalyses.h added (r1.2.4.2) Passes.h updated: 1.6 -> 1.6.4.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+102 -0) ConstantFolding.h | 36 +++++++++++++++++++++++++++++++ LinkAllAnalyses.h | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ Passes.h | 4 +++ 3 files changed, 102 insertions(+) Index: llvm/include/llvm/Analysis/ConstantFolding.h diff -c /dev/null llvm/include/llvm/Analysis/ConstantFolding.h:1.1.4.2 *** /dev/null Wed Nov 16 12:31:56 2005 --- llvm/include/llvm/Analysis/ConstantFolding.h Wed Nov 16 12:31:45 2005 *************** *** 0 **** --- 1,36 ---- + //===-- ConstantFolding.h - Analyze constant folding possibilities --------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This family of functions determines the possibility of performing constant + // folding. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Constants.h" + #include "llvm/Function.h" + using namespace llvm; + + namespace llvm { + + /// canConstantFoldCallTo - Return true if its even possible to fold a call to + /// the specified function. + extern + bool canConstantFoldCallTo(Function *F); + + /// ConstantFoldFP - Given a function that evaluates the constant, return an + /// LLVM Constant that represents the evaluated constant + extern Constant * + ConstantFoldFP(double (*NativeFP)(double), double V, const Type *Ty); + + /// ConstantFoldCall - Attempt to constant fold a call to the specified function + /// with the specified arguments, returning null if unsuccessful. + extern Constant * + ConstantFoldCall(Function *F, const std::vector &Operands); + } + Index: llvm/include/llvm/Analysis/LinkAllAnalyses.h diff -c /dev/null llvm/include/llvm/Analysis/LinkAllAnalyses.h:1.2.4.2 *** /dev/null Wed Nov 16 12:31:57 2005 --- llvm/include/llvm/Analysis/LinkAllAnalyses.h Wed Nov 16 12:31:46 2005 *************** *** 0 **** --- 1,62 ---- + //===- LinkAllAnalyses.h - Reference All Analysis Passes --------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Chris Lattner and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This header file pulls in all analysis passes for tools like analyze and + // bugpoint that need this functionality. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_ANALYSIS_LINKALLANALYSES_H + #define LLVM_ANALYSIS_LINKALLANALYSES_H + + #include "llvm/Analysis/AliasSetTracker.h" + #include "llvm/Analysis/CallGraph.h" + #include "llvm/Analysis/FindUsedTypes.h" + #include "llvm/Analysis/IntervalPartition.h" + #include "llvm/Analysis/PostDominators.h" + #include "llvm/Analysis/Passes.h" + #include "llvm/Analysis/ScalarEvolution.h" + #include "llvm/Analysis/DataStructure/DataStructure.h" + #include "llvm/Function.h" + #include + + namespace { + struct ForceAnalysisPassLinking { + ForceAnalysisPassLinking() { + // We must reference the passes in such a way that compilers will not + // delete it all as dead code, even with whole program optimization, + // yet is effectively a NO-OP. As the compiler isn't smart enough + // to know that getenv() never returns -1, this will do the job. + if (std::getenv("bar") != (char*) -1) + return; + + (void)new llvm::LocalDataStructures(); + (void)new llvm::BUDataStructures(); + (void)new llvm::TDDataStructures(); + (void)new llvm::CompleteBUDataStructures(); + (void)new llvm::EquivClassGraphs(); + (void)llvm::createDataStructureStatsPass(); + (void)llvm::createDataStructureGraphCheckerPass(); + (void)llvm::createProfileLoaderPass(); + (void)llvm::createNoProfileInfoPass(); + (void)llvm::createInstCountPass(); + (void)new llvm::IntervalPartition(); + (void)new llvm::ImmediateDominators(); + (void)new llvm::PostDominatorSet(); + (void)new llvm::CallGraph(); + (void)new llvm::FindUsedTypes(); + (void)new llvm::ScalarEvolution(); + ((llvm::Function*)0)->viewCFGOnly(); + llvm::AliasSetTracker X(*(llvm::AliasAnalysis*)0); + X.add((llvm::Value*)0, 0); // for -print-alias-sets + } + } ForceAnalysisPassLinking; + }; + + #endif Index: llvm/include/llvm/Analysis/Passes.h diff -u llvm/include/llvm/Analysis/Passes.h:1.6 llvm/include/llvm/Analysis/Passes.h:1.6.4.1 --- llvm/include/llvm/Analysis/Passes.h:1.6 Thu Apr 21 15:16:32 2005 +++ llvm/include/llvm/Analysis/Passes.h Wed Nov 16 12:31:46 2005 @@ -102,6 +102,10 @@ // simple context insensitive alias analysis. // ModulePass *createSteensgaardPass(); + + // Minor pass prototypes, allowing us to expose them through bugpoint and + // analyze. + FunctionPass *createInstCountPass(); } #endif From bocchino at cs.uiuc.edu Wed Nov 16 12:32:00 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:00 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/include/llvm/Analysis/DataStructure/DataStructure.h Message-ID: <200511161832.MAA20669@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis/DataStructure: DataStructure.h updated: 1.94.4.1 -> 1.94.4.2 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+4 -0) DataStructure.h | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/include/llvm/Analysis/DataStructure/DataStructure.h diff -u llvm/include/llvm/Analysis/DataStructure/DataStructure.h:1.94.4.1 llvm/include/llvm/Analysis/DataStructure/DataStructure.h:1.94.4.2 --- llvm/include/llvm/Analysis/DataStructure/DataStructure.h:1.94.4.1 Tue Oct 18 14:21:56 2005 +++ llvm/include/llvm/Analysis/DataStructure/DataStructure.h Wed Nov 16 12:31:48 2005 @@ -31,6 +31,10 @@ class DSNode; class DSNodeHandle; +FunctionPass *createDataStructureStatsPass(); +FunctionPass *createDataStructureGraphCheckerPass(); + + // FIXME: move this stuff to a private header namespace DataStructureAnalysis { /// isPointerType - Return true if this first class type is big enough to hold From bocchino at cs.uiuc.edu Wed Nov 16 12:32:02 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:02 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/include/llvm/CodeGen/AsmPrinter.h LiveInterval.h LiveIntervalAnalysis.h MachineFrameInfo.h Passes.h SelectionDAG.h SelectionDAGNodes.h Message-ID: <200511161832.MAA20691@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: AsmPrinter.h updated: 1.13 -> 1.13.4.1 LiveInterval.h updated: 1.14 -> 1.14.4.1 LiveIntervalAnalysis.h updated: 1.47 -> 1.47.2.1 MachineFrameInfo.h updated: 1.12 -> 1.12.4.1 Passes.h updated: 1.20 -> 1.20.4.1 SelectionDAG.h updated: 1.63 -> 1.63.2.1 SelectionDAGNodes.h updated: 1.69 -> 1.69.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+232 -103) AsmPrinter.h | 13 ++ LiveInterval.h | 5 + LiveIntervalAnalysis.h | 4 MachineFrameInfo.h | 21 ++++ Passes.h | 5 - SelectionDAG.h | 42 +++++--- SelectionDAGNodes.h | 245 ++++++++++++++++++++++++++++++++----------------- 7 files changed, 232 insertions(+), 103 deletions(-) Index: llvm/include/llvm/CodeGen/AsmPrinter.h diff -u llvm/include/llvm/CodeGen/AsmPrinter.h:1.13 llvm/include/llvm/CodeGen/AsmPrinter.h:1.13.4.1 --- llvm/include/llvm/CodeGen/AsmPrinter.h:1.13 Thu Apr 21 15:38:00 2005 +++ llvm/include/llvm/CodeGen/AsmPrinter.h Wed Nov 16 12:31:50 2005 @@ -77,7 +77,12 @@ /// AsciiDirective - This directive allows emission of an ascii string with /// the standard C escape characters embedded into it. - const char *AsciiDirective; + const char *AsciiDirective; // Defaults to "\t.ascii\t" + + /// AscizDirective - If not null, this allows for special handling of + /// zero terminated strings on this target. This is commonly supported as + /// ".asciz". If a target doesn't support this, it can be set to null. + const char *AscizDirective; // Defaults to "\t.asciz\t" /// DataDirectives - These directives are used to output some unit of /// integer data to the current section. If a data directive is set to @@ -108,6 +113,7 @@ FunctionAddrSuffix(""), ZeroDirective("\t.zero\t"), AsciiDirective("\t.ascii\t"), + AscizDirective("\t.asciz\t"), Data8bitsDirective("\t.byte\t"), Data16bitsDirective("\t.short\t"), Data32bitsDirective("\t.long\t"), @@ -131,8 +137,9 @@ /// emitAlignment - Emit an alignment directive to the specified power of /// two boundary. For example, if you pass in 3 here, you will get an 8 - /// byte alignment. - void emitAlignment(unsigned NumBits) const; + /// byte alignment. If a global value is specified, and if that global has + /// an explicit alignment requested, it will override the alignment request. + void emitAlignment(unsigned NumBits, const GlobalValue *GV = 0) const; /// emitZeros - Emit a block of zeros. /// Index: llvm/include/llvm/CodeGen/LiveInterval.h diff -u llvm/include/llvm/CodeGen/LiveInterval.h:1.14 llvm/include/llvm/CodeGen/LiveInterval.h:1.14.4.1 --- llvm/include/llvm/CodeGen/LiveInterval.h:1.14 Sat May 14 00:34:15 2005 +++ llvm/include/llvm/CodeGen/LiveInterval.h Wed Nov 16 12:31:50 2005 @@ -143,6 +143,11 @@ /// only overlaps with one value in the source interval. bool joinable(const LiveInterval& other, unsigned CopyIdx) const; + /// getOverlapingRanges - Given another live interval which is defined as a + /// copy from this one, return a list of all of the live ranges where the + /// two overlap and have different value numbers. + void getOverlapingRanges(const LiveInterval &Other, unsigned CopyIdx, + std::vector &Ranges); /// overlaps - Return true if the intersection of the two live intervals is /// not empty. Index: llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h diff -u llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h:1.47 llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h:1.47.2.1 --- llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h:1.47 Tue Sep 20 23:18:25 2005 +++ llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h Wed Nov 16 12:31:50 2005 @@ -171,6 +171,10 @@ /// register classes. The registers may be either phys or virt regs. bool differingRegisterClasses(unsigned RegA, unsigned RegB) const; + bool AdjustIfAllOverlappingRangesAreCopiesFrom(LiveInterval &IntA, + LiveInterval &IntB, + unsigned CopyIdx); + bool overlapsAliases(const LiveInterval *lhs, const LiveInterval *rhs) const; Index: llvm/include/llvm/CodeGen/MachineFrameInfo.h diff -u llvm/include/llvm/CodeGen/MachineFrameInfo.h:1.12 llvm/include/llvm/CodeGen/MachineFrameInfo.h:1.12.4.1 --- llvm/include/llvm/CodeGen/MachineFrameInfo.h:1.12 Thu Apr 21 15:38:00 2005 +++ llvm/include/llvm/CodeGen/MachineFrameInfo.h Wed Nov 16 12:31:50 2005 @@ -85,6 +85,15 @@ /// to be allocated on entry to the function. /// unsigned StackSize; + + /// MaxAlignment - The prolog/epilog code inserter may process objects + /// that require greater alignment than the default alignment the target + /// provides. To handle this, MaxAlignment is set to the maximum alignment + /// needed by the objects on the current frame. If this is greater than the + /// native alignment maintained by the compiler, dynamic alignment code will + /// be needed. + /// + unsigned MaxAlignment; /// HasCalls - Set to true if this function has any function calls. This is /// only valid during and after prolog/epilog code insertion. @@ -99,7 +108,7 @@ unsigned MaxCallFrameSize; public: MachineFrameInfo() { - NumFixedObjects = StackSize = 0; + NumFixedObjects = StackSize = MaxAlignment = 0; HasVarSizedObjects = false; HasCalls = false; MaxCallFrameSize = 0; @@ -163,6 +172,16 @@ /// void setStackSize(unsigned Size) { StackSize = Size; } + /// getMaxAlignment - Return the alignment in bytes that this function must be + /// aligned to, which is greater than the default stack alignment provided by + /// the target. + /// + unsigned getMaxAlignment() const { return MaxAlignment; } + + /// setMaxAlignment - Set the preferred alignment. + /// + void setMaxAlignment(unsigned Align) { MaxAlignment = Align; } + /// hasCalls - Return true if the current function has no function calls. /// This is only valid during or after prolog/epilog code emission. /// Index: llvm/include/llvm/CodeGen/Passes.h diff -u llvm/include/llvm/CodeGen/Passes.h:1.20 llvm/include/llvm/CodeGen/Passes.h:1.20.4.1 --- llvm/include/llvm/CodeGen/Passes.h:1.20 Sun May 1 11:14:34 2005 +++ llvm/include/llvm/CodeGen/Passes.h Wed Nov 16 12:31:50 2005 @@ -70,11 +70,6 @@ /// FunctionPass *createLinearScanRegisterAllocator(); - /// IterativeScanRegisterAllocation Pass - This pass implements the iterative - /// scan register allocation algorithm, a global register allocator. - /// - FunctionPass *createIterativeScanRegisterAllocator(); - /// PrologEpilogCodeInserter Pass - This pass inserts prolog and epilog code, /// and eliminates abstract frame references. /// Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.63 llvm/include/llvm/CodeGen/SelectionDAG.h:1.63.2.1 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.63 Wed Oct 12 22:10:46 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Wed Nov 16 12:31:50 2005 @@ -16,7 +16,10 @@ #define LLVM_CODEGEN_SELECTIONDAG_H #include "llvm/CodeGen/SelectionDAGNodes.h" +#include "llvm/ADT/ilist" + #include +#include #include // FIXME remove eventually, turning map into const char* map. namespace llvm { @@ -42,8 +45,8 @@ // Root - The root of the entire DAG. EntryNode - The starting token. SDOperand Root, EntryNode; - // AllNodes - All of the nodes in the DAG - std::vector AllNodes; + // AllNodes - A linked list of nodes in the current DAG. + ilist AllNodes; // ValueNodes - track SrcValue nodes std::map, SDNode*> ValueNodes; @@ -63,11 +66,13 @@ void viewGraph(); - typedef std::vector::const_iterator allnodes_iterator; - allnodes_iterator allnodes_begin() const { return AllNodes.begin(); } - allnodes_iterator allnodes_end() const { return AllNodes.end(); } - unsigned allnodes_size() const { return AllNodes.size(); } - + typedef ilist::const_iterator allnodes_const_iterator; + allnodes_const_iterator allnodes_begin() const { return AllNodes.begin(); } + allnodes_const_iterator allnodes_end() const { return AllNodes.end(); } + typedef ilist::iterator allnodes_iterator; + allnodes_iterator allnodes_begin() { return AllNodes.begin(); } + allnodes_iterator allnodes_end() { return AllNodes.end(); } + /// getRoot - Return the root tag of the SelectionDAG. /// const SDOperand &getRoot() const { return Root; } @@ -111,6 +116,7 @@ SDOperand getTargetConstantPool(Constant *C, MVT::ValueType VT); SDOperand getBasicBlock(MachineBasicBlock *MBB); SDOperand getExternalSymbol(const char *Sym, MVT::ValueType VT); + SDOperand getTargetExternalSymbol(const char *Sym, MVT::ValueType VT); SDOperand getValueType(MVT::ValueType); SDOperand getRegister(unsigned Reg, MVT::ValueType VT); @@ -171,7 +177,7 @@ SDOperand Callee, bool isTailCall = false) { SDNode *NN = new SDNode(isTailCall ? ISD::TAILCALL : ISD::CALL, Chain, Callee); - NN->setValueTypes(RetVals); + setNodeValueTypes(NN, RetVals); AllNodes.push_back(NN); return NN; } @@ -185,7 +191,7 @@ ArgsInRegs.insert(ArgsInRegs.begin(), Callee); ArgsInRegs.insert(ArgsInRegs.begin(), Chain); SDNode *NN = new SDNode(isTailCall ? ISD::TAILCALL : ISD::CALL, ArgsInRegs); - NN->setValueTypes(RetVals); + setNodeValueTypes(NN, RetVals); AllNodes.push_back(NN); return NN; } @@ -279,7 +285,10 @@ void SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT1, MVT::ValueType VT2, SDOperand Op1, SDOperand Op2, SDOperand Op3); - + + SDOperand getTargetNode(unsigned Opcode, MVT::ValueType VT) { + return getNode(ISD::BUILTIN_OP_END+Opcode, VT); + } SDOperand getTargetNode(unsigned Opcode, MVT::ValueType VT, SDOperand Op1) { return getNode(ISD::BUILTIN_OP_END+Opcode, VT, Op1); @@ -350,14 +359,20 @@ private: void RemoveNodeFromCSEMaps(SDNode *N); SDNode *AddNonLeafNodeToCSEMaps(SDNode *N); - void DeleteNodeIfDead(SDNode *N, void *NodeSet); + void DestroyDeadNode(SDNode *N); void DeleteNodeNotInCSEMaps(SDNode *N); + void setNodeValueTypes(SDNode *N, std::vector &RetVals); + void setNodeValueTypes(SDNode *N, MVT::ValueType VT1, MVT::ValueType VT2); + /// SimplifySetCC - Try to simplify a setcc built with the specified operands /// and cc. If unable to simplify it, return a null SDOperand. SDOperand SimplifySetCC(MVT::ValueType VT, SDOperand N1, SDOperand N2, ISD::CondCode Cond); - + + // List of non-single value types. + std::list > VTList; + // Maps to auto-CSE operations. std::map, SDNode *> NullaryOps; std::map >, @@ -382,6 +397,7 @@ std::map BBNodes; std::vector ValueTypeNodes; std::map ExternalSymbols; + std::map TargetExternalSymbols; std::map > >, SDNode*> OneResultNodes; @@ -401,6 +417,6 @@ } }; -} +} // end namespace llvm #endif Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.69 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.69.2.1 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.69 Wed Oct 5 01:34:34 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Wed Nov 16 12:31:50 2005 @@ -22,7 +22,6 @@ #include "llvm/CodeGen/ValueTypes.h" #include "llvm/Value.h" #include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/iterator" #include "llvm/Support/DataTypes.h" #include @@ -35,6 +34,9 @@ class MachineBasicBlock; class SDNode; template struct simplify_type; +template struct ilist_traits; +template class iplist; +template class ilist_iterator; /// ISD namespace - This namespace contains an enum which represents all of the /// SelectionDAG node types and value types. @@ -74,6 +76,7 @@ TargetGlobalAddress, TargetFrameIndex, TargetConstantPool, + TargetExternalSymbol, // CopyToReg - This node has three operands: a chain, a register number to // set to this value, and a value. @@ -304,6 +307,12 @@ // PCMARKER - This corresponds to the pcmarker intrinsic. PCMARKER, + // READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic. + // The only operand is a chain and a value and a chain are produced. The + // value is the contents of the architecture specific cycle counter like + // register (or other high accuracy low latency clock source) + READCYCLECOUNTER, + // READPORT, WRITEPORT, READIO, WRITEIO - These correspond to the LLVM // intrinsics of the same name. The first operand is a token chain, the // other operands match the intrinsic. These produce a token chain in @@ -490,19 +499,30 @@ /// depth of 2, etc. unsigned short NodeDepth; - /// Operands - The values that are used by this operation. + /// OperandList - The values that are used by this operation. /// - std::vector Operands; + SDOperand *OperandList; + + /// ValueList - The types of the values this node defines. SDNode's may + /// define multiple values simultaneously. + MVT::ValueType *ValueList; - /// Values - The types of the values this node defines. SDNode's may define - /// multiple values simultaneously. - std::vector Values; + /// NumOperands/NumValues - The number of entries in the Operand/Value list. + unsigned short NumOperands, NumValues; + + /// Prev/Next pointers - These pointers form the linked list of of the + /// AllNodes list in the current DAG. + SDNode *Prev, *Next; + friend struct ilist_traits; /// Uses - These are all of the SDNode's that use a value produced by this /// node. std::vector Uses; public: - + virtual ~SDNode() { + assert(NumOperands == 0 && "Operand list not cleared before deletion"); + } + //===--------------------------------------------------------------------===// // Accessors // @@ -532,37 +552,32 @@ /// getNumOperands - Return the number of values used by this operation. /// - unsigned getNumOperands() const { return Operands.size(); } - - const SDOperand &getOperand(unsigned Num) { - assert(Num < Operands.size() && "Invalid child # of SDNode!"); - return Operands[Num]; - } + unsigned getNumOperands() const { return NumOperands; } const SDOperand &getOperand(unsigned Num) const { - assert(Num < Operands.size() && "Invalid child # of SDNode!"); - return Operands[Num]; + assert(Num < NumOperands && "Invalid child # of SDNode!"); + return OperandList[Num]; } - typedef std::vector::const_iterator op_iterator; - op_iterator op_begin() const { return Operands.begin(); } - op_iterator op_end() const { return Operands.end(); } + typedef const SDOperand* op_iterator; + op_iterator op_begin() const { return OperandList; } + op_iterator op_end() const { return OperandList+NumOperands; } /// getNumValues - Return the number of values defined/returned by this /// operator. /// - unsigned getNumValues() const { return Values.size(); } + unsigned getNumValues() const { return NumValues; } /// getValueType - Return the type of a specified result. /// MVT::ValueType getValueType(unsigned ResNo) const { - assert(ResNo < Values.size() && "Illegal result number!"); - return Values[ResNo]; + assert(ResNo < NumValues && "Illegal result number!"); + return ValueList[ResNo]; } - typedef std::vector::const_iterator value_iterator; - value_iterator value_begin() const { return Values.begin(); } - value_iterator value_end() const { return Values.end(); } + typedef const MVT::ValueType* value_iterator; + value_iterator value_begin() const { return ValueList; } + value_iterator value_end() const { return ValueList+NumValues; } /// getOperationName - Return the opcode of this operation for printing. /// @@ -578,15 +593,26 @@ protected: friend class SelectionDAG; + + /// getValueTypeList - Return a pointer to the specified value type. + /// + static MVT::ValueType *getValueTypeList(MVT::ValueType VT); SDNode(unsigned NT, MVT::ValueType VT) : NodeType(NT), NodeDepth(1) { - Values.reserve(1); - Values.push_back(VT); + OperandList = 0; NumOperands = 0; + ValueList = getValueTypeList(VT); + NumValues = 1; + Prev = 0; Next = 0; } SDNode(unsigned NT, SDOperand Op) : NodeType(NT), NodeDepth(Op.Val->getNodeDepth()+1) { - Operands.reserve(1); Operands.push_back(Op); + OperandList = new SDOperand[1]; + OperandList[0] = Op; + NumOperands = 1; Op.Val->Uses.push_back(this); + ValueList = 0; + NumValues = 0; + Prev = 0; Next = 0; } SDNode(unsigned NT, SDOperand N1, SDOperand N2) : NodeType(NT) { @@ -594,8 +620,14 @@ NodeDepth = N1.Val->getNodeDepth()+1; else NodeDepth = N2.Val->getNodeDepth()+1; - Operands.reserve(2); Operands.push_back(N1); Operands.push_back(N2); + OperandList = new SDOperand[2]; + OperandList[0] = N1; + OperandList[1] = N2; + NumOperands = 2; N1.Val->Uses.push_back(this); N2.Val->Uses.push_back(this); + ValueList = 0; + NumValues = 0; + Prev = 0; Next = 0; } SDNode(unsigned NT, SDOperand N1, SDOperand N2, SDOperand N3) : NodeType(NT) { @@ -606,10 +638,17 @@ ND = N3.Val->getNodeDepth(); NodeDepth = ND+1; - Operands.reserve(3); Operands.push_back(N1); Operands.push_back(N2); - Operands.push_back(N3); + OperandList = new SDOperand[3]; + OperandList[0] = N1; + OperandList[1] = N2; + OperandList[2] = N3; + NumOperands = 3; + N1.Val->Uses.push_back(this); N2.Val->Uses.push_back(this); N3.Val->Uses.push_back(this); + ValueList = 0; + NumValues = 0; + Prev = 0; Next = 0; } SDNode(unsigned NT, SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4) : NodeType(NT) { @@ -622,90 +661,110 @@ ND = N4.Val->getNodeDepth(); NodeDepth = ND+1; - Operands.reserve(4); Operands.push_back(N1); Operands.push_back(N2); - Operands.push_back(N3); Operands.push_back(N4); + OperandList = new SDOperand[4]; + OperandList[0] = N1; + OperandList[1] = N2; + OperandList[2] = N3; + OperandList[3] = N4; + NumOperands = 4; + N1.Val->Uses.push_back(this); N2.Val->Uses.push_back(this); N3.Val->Uses.push_back(this); N4.Val->Uses.push_back(this); - } - SDNode(unsigned NT, std::vector &Nodes) : NodeType(NT) { - Operands.swap(Nodes); + ValueList = 0; + NumValues = 0; + Prev = 0; Next = 0; + } + SDNode(unsigned Opc, const std::vector &Nodes) : NodeType(Opc) { + NumOperands = Nodes.size(); + OperandList = new SDOperand[NumOperands]; + unsigned ND = 0; - for (unsigned i = 0, e = Operands.size(); i != e; ++i) { - Operands[i].Val->Uses.push_back(this); - if (ND < Operands[i].Val->getNodeDepth()) - ND = Operands[i].Val->getNodeDepth(); + for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { + OperandList[i] = Nodes[i]; + SDNode *N = OperandList[i].Val; + N->Uses.push_back(this); + if (ND < N->getNodeDepth()) ND = N->getNodeDepth(); } NodeDepth = ND+1; + ValueList = 0; + NumValues = 0; + Prev = 0; Next = 0; } - virtual ~SDNode() {} - /// MorphNodeTo - This clears the return value and operands list, and sets the /// opcode of the node to the specified value. This should only be used by /// the SelectionDAG class. void MorphNodeTo(unsigned Opc) { NodeType = Opc; - Values.clear(); + ValueList = 0; + NumValues = 0; // Clear the operands list, updating used nodes to remove this from their // use list. - while (!Operands.empty()) { - SDNode *O = Operands.back().Val; - Operands.pop_back(); - O->removeUser(this); - } + for (op_iterator I = op_begin(), E = op_end(); I != E; ++I) + I->Val->removeUser(this); + delete [] OperandList; + OperandList = 0; + NumOperands = 0; } void setValueTypes(MVT::ValueType VT) { - Values.reserve(1); - Values.push_back(VT); - } - void setValueTypes(MVT::ValueType VT1, MVT::ValueType VT2) { - Values.reserve(2); - Values.push_back(VT1); - Values.push_back(VT2); - } - /// Note: this method destroys the vector passed in. - void setValueTypes(std::vector &VTs) { - std::swap(Values, VTs); + assert(NumValues == 0 && "Should not have values yet!"); + ValueList = getValueTypeList(VT); + NumValues = 1; + } + void setValueTypes(MVT::ValueType *List, unsigned NumVal) { + assert(NumValues == 0 && "Should not have values yet!"); + ValueList = List; + NumValues = NumVal; } void setOperands(SDOperand Op0) { - Operands.reserve(1); - Operands.push_back(Op0); + assert(NumOperands == 0 && "Should not have operands yet!"); + OperandList = new SDOperand[1]; + OperandList[0] = Op0; + NumOperands = 1; Op0.Val->Uses.push_back(this); } void setOperands(SDOperand Op0, SDOperand Op1) { - Operands.reserve(2); - Operands.push_back(Op0); - Operands.push_back(Op1); + assert(NumOperands == 0 && "Should not have operands yet!"); + OperandList = new SDOperand[2]; + OperandList[0] = Op0; + OperandList[1] = Op1; + NumOperands = 2; Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this); } void setOperands(SDOperand Op0, SDOperand Op1, SDOperand Op2) { - Operands.reserve(3); - Operands.push_back(Op0); - Operands.push_back(Op1); - Operands.push_back(Op2); + assert(NumOperands == 0 && "Should not have operands yet!"); + OperandList = new SDOperand[3]; + OperandList[0] = Op0; + OperandList[1] = Op1; + OperandList[2] = Op2; + NumOperands = 3; Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this); Op2.Val->Uses.push_back(this); } void setOperands(SDOperand Op0, SDOperand Op1, SDOperand Op2, SDOperand Op3) { - Operands.reserve(4); - Operands.push_back(Op0); - Operands.push_back(Op1); - Operands.push_back(Op2); - Operands.push_back(Op3); + assert(NumOperands == 0 && "Should not have operands yet!"); + OperandList = new SDOperand[4]; + OperandList[0] = Op0; + OperandList[1] = Op1; + OperandList[2] = Op2; + OperandList[3] = Op3; + NumOperands = 4; Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this); Op2.Val->Uses.push_back(this); Op3.Val->Uses.push_back(this); } void setOperands(SDOperand Op0, SDOperand Op1, SDOperand Op2, SDOperand Op3, SDOperand Op4) { - Operands.reserve(5); - Operands.push_back(Op0); - Operands.push_back(Op1); - Operands.push_back(Op2); - Operands.push_back(Op3); - Operands.push_back(Op4); + assert(NumOperands == 0 && "Should not have operands yet!"); + OperandList = new SDOperand[5]; + OperandList[0] = Op0; + OperandList[1] = Op1; + OperandList[2] = Op2; + OperandList[3] = Op3; + OperandList[4] = Op4; + NumOperands = 5; Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this); Op2.Val->Uses.push_back(this); Op3.Val->Uses.push_back(this); Op4.Val->Uses.push_back(this); @@ -932,8 +991,9 @@ const char *Symbol; protected: friend class SelectionDAG; - ExternalSymbolSDNode(const char *Sym, MVT::ValueType VT) - : SDNode(ISD::ExternalSymbol, VT), Symbol(Sym) { + ExternalSymbolSDNode(bool isTarget, const char *Sym, MVT::ValueType VT) + : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol, VT), + Symbol(Sym) { } public: @@ -941,7 +1001,8 @@ static bool classof(const ExternalSymbolSDNode *) { return true; } static bool classof(const SDNode *N) { - return N->getOpcode() == ISD::ExternalSymbol; + return N->getOpcode() == ISD::ExternalSymbol || + N->getOpcode() == ISD::TargetExternalSymbol; } }; @@ -1032,6 +1093,28 @@ } }; +template<> +struct ilist_traits { + static SDNode *getPrev(const SDNode *N) { return N->Prev; } + static SDNode *getNext(const SDNode *N) { return N->Next; } + + static void setPrev(SDNode *N, SDNode *Prev) { N->Prev = Prev; } + static void setNext(SDNode *N, SDNode *Next) { N->Next = Next; } + + static SDNode *createSentinel() { + return new SDNode(ISD::EntryToken, MVT::Other); + } + static void destroySentinel(SDNode *N) { delete N; } + //static SDNode *createNode(const SDNode &V) { return new SDNode(V); } + + + void addNodeToList(SDNode *NTy) {} + void removeNodeFromList(SDNode *NTy) {} + void transferNodesFromList(iplist &L2, + const ilist_iterator &X, + const ilist_iterator &Y) {} +}; + } // end llvm namespace #endif From bocchino at cs.uiuc.edu Wed Nov 16 12:32:05 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:05 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/include/llvm/Config/config.h.in Message-ID: <200511161832.MAA20704@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Config: config.h.in updated: 1.57 -> 1.57.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+6 -0) config.h.in | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/include/llvm/Config/config.h.in diff -u llvm/include/llvm/Config/config.h.in:1.57 llvm/include/llvm/Config/config.h.in:1.57.2.1 --- llvm/include/llvm/Config/config.h.in:1.57 Wed Aug 24 05:07:21 2005 +++ llvm/include/llvm/Config/config.h.in Wed Nov 16 12:31:53 2005 @@ -185,6 +185,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_MALLOC_H + +/* Define to 1 if you have the `malloc_zone_statistics' function. */ +#undef HAVE_MALLOC_ZONE_STATISTICS + /* Define to 1 if you have the `memcpy' function. */ #undef HAVE_MEMCPY From bocchino at cs.uiuc.edu Wed Nov 16 12:32:07 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:07 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/include/llvm/Support/CommandLine.h DataTypes.h.in Mangler.h Message-ID: <200511161832.MAA20718@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Support: CommandLine.h updated: 1.49 -> 1.49.2.1 DataTypes.h.in updated: 1.20 -> 1.20.2.1 Mangler.h updated: 1.14 -> 1.14.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+59 -18) CommandLine.h | 5 ++-- DataTypes.h.in | 7 ++++++ Mangler.h | 65 ++++++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 59 insertions(+), 18 deletions(-) Index: llvm/include/llvm/Support/CommandLine.h diff -u llvm/include/llvm/Support/CommandLine.h:1.49 llvm/include/llvm/Support/CommandLine.h:1.49.2.1 --- llvm/include/llvm/Support/CommandLine.h:1.49 Thu Oct 13 19:33:05 2005 +++ llvm/include/llvm/Support/CommandLine.h Wed Nov 16 12:31:56 2005 @@ -21,6 +21,7 @@ #define LLVM_SUPPORT_COMMANDLINE_H #include "llvm/Support/type_traits.h" +#include "llvm/Support/DataTypes.h" #include #include #include @@ -334,8 +335,8 @@ }; template -ValuesClass values(const char *Arg, DataType Val, const char *Desc, - ...) { +ValuesClass END_WITH_NULL values(const char *Arg, DataType Val, + const char *Desc, ...) { va_list ValueArgs; va_start(ValueArgs, Desc); ValuesClass Vals(Arg, Val, Desc, ValueArgs); Index: llvm/include/llvm/Support/DataTypes.h.in diff -u llvm/include/llvm/Support/DataTypes.h.in:1.20 llvm/include/llvm/Support/DataTypes.h.in:1.20.2.1 --- llvm/include/llvm/Support/DataTypes.h.in:1.20 Wed Jul 27 00:53:43 2005 +++ llvm/include/llvm/Support/DataTypes.h.in Wed Nov 16 12:31:56 2005 @@ -67,6 +67,7 @@ // Visual C++ doesn't provide standard integer headers, but it does provide // built-in data types. #include +#include typedef __int64 int64_t; typedef unsigned __int64 uint64_t; typedef signed int int32_t; @@ -98,4 +99,10 @@ # define UINT64_MAX 0xffffffffffffffffULL #endif +#if __GNUC__ > 3 +#define END_WITH_NULL __attribute__((sentinel)) +#else +#define END_WITH_NULL +#endif + #endif /* SUPPORT_DATATYPES_H */ Index: llvm/include/llvm/Support/Mangler.h diff -u llvm/include/llvm/Support/Mangler.h:1.14 llvm/include/llvm/Support/Mangler.h:1.14.2.1 --- llvm/include/llvm/Support/Mangler.h:1.14 Sat Sep 24 03:23:53 2005 +++ llvm/include/llvm/Support/Mangler.h Wed Nov 16 12:31:56 2005 @@ -19,35 +19,65 @@ #include namespace llvm { -class Value; class Type; class Module; +class Value; class GlobalValue; class Mangler { - /// This keeps track of which global values have had their names - /// mangled in the current module. - /// - std::set MangledGlobals; - - Module &M; + /// Prefix - This string is added to each symbol that is emitted, unless the + /// symbol is marked as not needing this prefix. const char *Prefix; + + /// UseQuotes - If this is set, the target accepts global names in quotes, + /// e.g. "foo bar" is a legal name. This syntax is used instead of escaping + /// the space character. By default, this is false. + bool UseQuotes; + + /// Memo - This is used to remember the name that we assign a value. + /// + std::map Memo; - unsigned TypeCounter; - std::map TypeMap; - - typedef std::map ValueMap; - ValueMap Memo; - + /// Count - This simple counter is used to unique value names. + /// unsigned Count; + + /// TypeMap - If the client wants us to unique types, this keeps track of the + /// current assignments and TypeCounter keeps track of the next id to assign. + std::map TypeMap; + unsigned TypeCounter; - void InsertName(GlobalValue *GV, std::map &Names); + /// This keeps track of which global values have had their names + /// mangled in the current module. + /// + std::set MangledGlobals; + + /// AcceptableChars - This bitfield contains a one for each character that is + /// allowed to be part of an unmangled name. + unsigned AcceptableChars[256/32]; public: // Mangler ctor - if a prefix is specified, it will be prepended onto all // symbols. Mangler(Module &M, const char *Prefix = ""); + /// setUseQuotes - If UseQuotes is set to true, this target accepts quoted + /// strings for assembler labels. + void setUseQuotes(bool Val) { UseQuotes = Val; } + + /// Acceptable Characters - This allows the target to specify which characters + /// are acceptable to the assembler without being mangled. By default we + /// allow letters, numbers, '_', '$', and '.', which is what GAS accepts. + void markCharAcceptable(unsigned char X) { + AcceptableChars[X/32] |= 1 << (X&31); + } + void markCharUnacceptable(unsigned char X) { + AcceptableChars[X/32] &= ~(1 << (X&31)); + } + bool isCharAcceptable(unsigned char X) const { + return (AcceptableChars[X/32] & (1 << (X&31))) != 0; + } + /// getTypeID - Return a unique ID for the specified LLVM type. /// unsigned getTypeID(const Type *Ty); @@ -55,6 +85,7 @@ /// getValueName - Returns the mangled name of V, an LLVM Value, /// in the current module. /// + std::string getValueName(const GlobalValue *V); std::string getValueName(const Value *V); /// makeNameProper - We don't want identifier names with ., space, or @@ -64,8 +95,10 @@ /// does this for you, so there's no point calling it on the result /// from getValueName. /// - static std::string makeNameProper(const std::string &x, - const char *Prefix = ""); + std::string makeNameProper(const std::string &x, const char *Prefix = ""); + +private: + void InsertName(GlobalValue *GV, std::map &Names); }; } // End llvm namespace From bocchino at cs.uiuc.edu Wed Nov 16 12:32:09 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:09 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/include/llvm/Target/SubtargetFeature.h TargetInstrInfo.h TargetInstrItineraries.h TargetLowering.h TargetMachine.h Message-ID: <200511161832.MAA20739@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: SubtargetFeature.h updated: 1.3 -> 1.3.2.1 TargetInstrInfo.h updated: 1.80 -> 1.80.2.1 TargetInstrItineraries.h added (r1.6.2.2) TargetLowering.h updated: 1.24 -> 1.24.2.1 TargetMachine.h updated: 1.57 -> 1.57.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+165 -81) SubtargetFeature.h | 109 ++++++++++++++--------------------------------- TargetInstrInfo.h | 1 TargetInstrItineraries.h | 84 ++++++++++++++++++++++++++++++++++++ TargetLowering.h | 37 +++++++++++++++ TargetMachine.h | 15 +++++- 5 files changed, 165 insertions(+), 81 deletions(-) Index: llvm/include/llvm/Target/SubtargetFeature.h diff -u llvm/include/llvm/Target/SubtargetFeature.h:1.3 llvm/include/llvm/Target/SubtargetFeature.h:1.3.2.1 --- llvm/include/llvm/Target/SubtargetFeature.h:1.3 Fri Sep 2 14:27:43 2005 +++ llvm/include/llvm/Target/SubtargetFeature.h Wed Nov 16 12:31:58 2005 @@ -18,11 +18,9 @@ #ifndef LLVM_TARGET_SUBTARGETFEATURE_H #define LLVM_TARGET_SUBTARGETFEATURE_H - #include #include -#include -#include +#include #include "llvm/Support/DataTypes.h" namespace llvm { @@ -45,6 +43,21 @@ //===----------------------------------------------------------------------===// /// +/// SubtargetInfoKV - Used to provide key value pairs for CPU and arbitrary +/// pointers. +// +struct SubtargetInfoKV { + const char *Key; // K-V key string + void *Value; // K-V pointer value + + // Compare routine for std binary search + bool operator<(const std::string &S) const { + return strcmp(Key, S.c_str()) < 0; + } +}; + +//===----------------------------------------------------------------------===// +/// /// SubtargetFeatures - Manages the enabling and disabling of subtarget /// specific features. Features are encoded as a string of the form /// "cpu,+attr1,+attr2,-attr3,...,+attrN" @@ -57,87 +70,31 @@ /// class SubtargetFeatures { -private: std::vector Features; // Subtarget features as a vector - - // Determine if a feature has a flag; '+' or '-' - static inline bool hasFlag(const std::string &Feature) { - assert(!Feature.empty() && "Empty string"); - // Get first character - char Ch = Feature[0]; - // Check if first character is '+' or '-' flag - return Ch == '+' || Ch =='-'; - } - - // Return true if enable flag; '+'. - static inline bool isEnabled(const std::string &Feature) { - assert(!Feature.empty() && "Empty string"); - // Get first character - char Ch = Feature[0]; - // Check if first character is '+' for enabled - return Ch == '+'; - } - - // Return a string with a prepended flag; '+' or '-'. - static inline std::string PrependFlag(const std::string &Feature, - bool IsEnabled) { - assert(!Feature.empty() && "Empty string"); - if (hasFlag(Feature)) return Feature; - return std::string(IsEnabled ? "+" : "-") + Feature; - } - - // Return string stripped of flag. - static inline std::string StripFlag(const std::string &Feature) { - return hasFlag(Feature) ? Feature.substr(1) : Feature; - } - - /// Splits a string of comma separated items in to a vector of strings. - static void Split(std::vector &V, const std::string &S); - - /// Join a vector of strings into a string with a comma separating each - /// item. - static std::string Join(const std::vector &V); - - /// Convert a string to lowercase. - static std::string toLower(const std::string &S); - - /// Find item in array using binary search. - static const SubtargetFeatureKV *Find(const std::string &S, - const SubtargetFeatureKV *A, size_t L); - public: - /// Ctor. - SubtargetFeatures(const std::string Initial = std::string()) { - // Break up string into separate features - Split(Features, Initial); - } + SubtargetFeatures(const std::string &Initial = std::string()); /// Features string accessors. - inline std::string getString() const { return Join(Features); } - void setString(const std::string &Initial) { - // Throw out old features - Features.clear(); - // Break up string into separate features - Split(Features, toLower(Initial)); - } + std::string getString() const; + void setString(const std::string &Initial); - /// Setting CPU string. Replaces previous setting. Setting to "" clears CPU. - void setCPU(std::string String) { Features[0] = toLower(String); } + /// Set the CPU string. Replaces previous setting. Setting to "" clears CPU. + void setCPU(const std::string &String); + + /// Setting CPU string only if no string is set. + void setCPUIfNone(const std::string &String); /// Adding Features. void AddFeature(const std::string &String, bool IsEnabled = true); - - /// Display help for feature choices. - static void Help(const char *Heading, - const SubtargetFeatureKV *Table, size_t TableSize); - - /// Parse feature string for quick usage. - static uint32_t Parse(const std::string &String, - const std::string &DefaultCPU, - const SubtargetFeatureKV *CPUTable, - size_t CPUTableSize, - const SubtargetFeatureKV *FeatureTable, - size_t FeatureTableSize); + + /// Get feature bits. + uint32_t getBits(const SubtargetFeatureKV *CPUTable, + size_t CPUTableSize, + const SubtargetFeatureKV *FeatureTable, + size_t FeatureTableSize); + + /// Get info pointer + void *getInfo(const SubtargetInfoKV *Table, size_t TableSize); /// Print feature string. void print(std::ostream &OS) const; Index: llvm/include/llvm/Target/TargetInstrInfo.h diff -u llvm/include/llvm/Target/TargetInstrInfo.h:1.80 llvm/include/llvm/Target/TargetInstrInfo.h:1.80.2.1 --- llvm/include/llvm/Target/TargetInstrInfo.h:1.80 Fri Sep 2 13:16:20 2005 +++ llvm/include/llvm/Target/TargetInstrInfo.h Wed Nov 16 12:31:58 2005 @@ -146,7 +146,6 @@ return get(Opcode).numOperands; } - InstrSchedClass getSchedClass(MachineOpCode Opcode) const { return get(Opcode).schedClass; } Index: llvm/include/llvm/Target/TargetInstrItineraries.h diff -c /dev/null llvm/include/llvm/Target/TargetInstrItineraries.h:1.6.2.2 *** /dev/null Wed Nov 16 12:32:09 2005 --- llvm/include/llvm/Target/TargetInstrItineraries.h Wed Nov 16 12:31:58 2005 *************** *** 0 **** --- 1,84 ---- + //===-- llvm/Target/TargetInstrItineraries.h - Scheduling -------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the James M. Laskey and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file describes the structures used for instruction itineraries and + // states. This is used by schedulers to determine instruction states and + // latencies. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_TARGET_TARGETINSTRITINERARIES_H + #define LLVM_TARGET_TARGETINSTRITINERARIES_H + + namespace llvm { + + //===----------------------------------------------------------------------===// + // Instruction stage - These values represent a step in the execution of an + // instruction. The latency represents the number of discrete time slots used + // need to complete the stage. Units represent the choice of functional units + // that can be used to complete the stage. Eg. IntUnit1, IntUnit2. + // + struct InstrStage { + unsigned Cycles; // Length of stage in machine cycles + unsigned Units; // Choice of functional units + }; + + + //===----------------------------------------------------------------------===// + // Instruction itinerary - An itinerary represents a sequential series of steps + // required to complete an instruction. Itineraries are represented as + // sequences of instruction stages. + // + struct InstrItinerary { + unsigned First; // Index of first stage in itinerary + unsigned Last; // Index of last + 1 stage in itinerary + }; + + + + //===----------------------------------------------------------------------===// + // Instruction itinerary Data - Itinerary data supplied by a subtarget to be + // used by a target. + // + struct InstrItineraryData { + InstrStage *Stages; // Array of stages selected + InstrItinerary *Itineratries; // Array of itineraries selected + + // + // Ctors. + // + InstrItineraryData() : Stages(0), Itineratries(0) {} + InstrItineraryData(InstrStage *S, InstrItinerary *I) : Stages(S), Itineratries(I) {} + + // + // isEmpty - Returns true if there are no itineraries. + // + inline bool isEmpty() const { return Itineratries == 0; } + + // + // begin - Return the first stage of the itinerary. + // + inline InstrStage *begin(unsigned ItinClassIndx) const { + unsigned StageIdx = Itineratries[ItinClassIndx].First; + return Stages + StageIdx; + } + + // + // end - Return the last+1 stage of the itinerary. + // + inline InstrStage *end(unsigned ItinClassIndx) const { + unsigned StageIdx = Itineratries[ItinClassIndx].Last; + return Stages + StageIdx; + } + }; + + + } // End llvm namespace + + #endif Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.24 llvm/include/llvm/Target/TargetLowering.h:1.24.2.1 --- llvm/include/llvm/Target/TargetLowering.h:1.24 Tue Sep 27 17:13:36 2005 +++ llvm/include/llvm/Target/TargetLowering.h Wed Nov 16 12:31:58 2005 @@ -83,7 +83,15 @@ /// isSetCCExpensive - Return true if the setcc operation is expensive for /// this target. bool isSetCCExpensive() const { return SetCCIsExpensive; } - + + /// isIntDivCheap() - Return true if integer divide is usually cheaper than + /// a sequence of several shifts, adds, and multiplies for this target. + bool isIntDivCheap() const { return IntDivIsCheap; } + + /// isPow2DivCheap() - Return true if pow2 div is cheaper than a chain of + /// srl/add/sra. + bool isPow2DivCheap() const { return Pow2DivIsCheap; } + /// getSetCCResultTy - Return the ValueType of the result of setcc operations. /// MVT::ValueType getSetCCResultTy() const { return SetCCResultTy; } @@ -262,6 +270,16 @@ /// setcc operations into other operations if possible. void setSetCCIsExpensive() { SetCCIsExpensive = true; } + /// setIntDivIsCheap - Tells the code generator that integer divide is + /// expensive, and if possible, should be replaced by an alternate sequence + /// of instructions not containing an integer divide. + void setIntDivIsCheap(bool isCheap = true) { IntDivIsCheap = isCheap; } + + /// setPow2DivIsCheap - Tells the code generator that it shouldn't generate + /// srl/add/sra for a signed divide by power of two, and let the target handle + /// it. + void setPow2DivIsCheap(bool isCheap = true) { Pow2DivIsCheap = isCheap; } + /// addRegisterClass - Add the specified register class as an available /// regclass for the specified value type. This indicates the selector can /// handle values of that class natively. @@ -311,6 +329,12 @@ unsigned CallingConv, bool isTailCall, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG) = 0; + /// LowerReturnTo - This hook lowers a return instruction into the appropriate + /// legal ISD::RET node for the target's current ABI. This method is optional + /// and is intended for targets that need non-standard behavior. + virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op, + SelectionDAG &DAG); + /// LowerVAStart - This lowers the llvm.va_start intrinsic. If not /// implemented, this method prints a message and aborts. This method should /// return the modified chain value. Note that VAListPtr* correspond to the @@ -385,6 +409,17 @@ /// setcc operations into other operations if possible. bool SetCCIsExpensive; + /// IntDivIsCheap - Tells the code generator not to expand integer divides by + /// constants into a sequence of muls, adds, and shifts. This is a hack until + /// a real cost model is in place. If we ever optimize for size, this will be + /// set to true unconditionally. + bool IntDivIsCheap; + + /// Pow2DivIsCheap - Tells the code generator that it shouldn't generate + /// srl/add/sra for a signed divide by power of two, and let the target handle + /// it. + bool Pow2DivIsCheap; + /// SetCCResultTy - The type that SetCC operations use. This defaults to the /// PointerTy. MVT::ValueType SetCCResultTy; Index: llvm/include/llvm/Target/TargetMachine.h diff -u llvm/include/llvm/Target/TargetMachine.h:1.57 llvm/include/llvm/Target/TargetMachine.h:1.57.2.1 --- llvm/include/llvm/Target/TargetMachine.h:1.57 Fri Aug 5 16:53:21 2005 +++ llvm/include/llvm/Target/TargetMachine.h Wed Nov 16 12:31:58 2005 @@ -15,6 +15,7 @@ #define LLVM_TARGET_TARGETMACHINE_H #include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetInstrItineraries.h" #include namespace llvm { @@ -122,6 +123,13 @@ /// otherwise return null. /// virtual TargetJITInfo *getJITInfo() { return 0; } + + /// getInstrItineraryData - Returns instruction itinerary data for the target + /// or specific subtarget. + /// + virtual const InstrItineraryData getInstrItineraryData() const { + return InstrItineraryData(); + } // These are deprecated interfaces. virtual const TargetSchedInfo *getSchedInfo() const { return 0; } @@ -135,11 +143,12 @@ /// addPassesToEmitFile - Add passes to the specified pass manager to get /// the specified file emitted. Typically this will involve several steps of - /// code generation. This method should return true if emission of this file - /// type is not supported. + /// code generation. If Fast is set to true, the code generator should emit + /// code as fast as possible, without regard for compile time. This method + /// should return true if emission of this file type is not supported. /// virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType) { + CodeGenFileType FileType, bool Fast) { return true; } From bocchino at cs.uiuc.edu Wed Nov 16 12:32:11 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:11 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/include/llvm/Transforms/LinkAllPasses.h Scalar.h Message-ID: <200511161832.MAA20752@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: LinkAllPasses.h updated: 1.19.4.1 -> 1.19.4.2 Scalar.h updated: 1.56.4.1 -> 1.56.4.2 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+29 -27) LinkAllPasses.h | 35 ++++++++++++++--------------------- Scalar.h | 21 +++++++++++++++------ 2 files changed, 29 insertions(+), 27 deletions(-) Index: llvm/include/llvm/Transforms/LinkAllPasses.h diff -u llvm/include/llvm/Transforms/LinkAllPasses.h:1.19.4.1 llvm/include/llvm/Transforms/LinkAllPasses.h:1.19.4.2 --- llvm/include/llvm/Transforms/LinkAllPasses.h:1.19.4.1 Tue Oct 18 14:21:56 2005 +++ llvm/include/llvm/Transforms/LinkAllPasses.h Wed Nov 16 12:32:00 2005 @@ -7,17 +7,14 @@ // //===----------------------------------------------------------------------===// // -// This header file is required for building with Microsoft's VC++, as it has -// no way of linking all registered passes into executables other than by -// explicit use. +// This header file pulls in all transformation passes for tools like opts and +// bugpoint that need this functionality. // //===----------------------------------------------------------------------===// #ifndef LLVM_TRANSFORMS_LINKALLPASSES_H #define LLVM_TRANSFORMS_LINKALLPASSES_H -#ifdef _MSC_VER - #include "llvm/Analysis/Passes.h" #include "llvm/Analysis/LoadValueNumbering.h" #include "llvm/CodeGen/Passes.h" @@ -25,20 +22,16 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" - -// Trying not to include , though maybe we should... Problem is, -// it pollutes the global namespace in some really nasty ways. -extern "C" __declspec(dllimport) void* __stdcall GetCurrentProcess(); +#include namespace { struct ForcePassLinking { ForcePassLinking() { - // We must reference the passes in such a way that VC++ will not + // We must reference the passes in such a way that compilers will not // delete it all as dead code, even with whole program optimization, // yet is effectively a NO-OP. As the compiler isn't smart enough - // to know that GetCurrentProcess() never returns - // INVALID_HANDLE_VALUE, this will do the job. - if (GetCurrentProcess() != (void *) -1) + // to know that getenv() never returns -1, this will do the job. + if (std::getenv("bar") != (char*) -1) return; (void) llvm::createAAEvalPass(); @@ -52,7 +45,6 @@ (void) llvm::createBlockProfilerPass(); (void) llvm::createBreakCriticalEdgesPass(); (void) llvm::createCFGSimplificationPass(); - (void) llvm::createCombineBranchesPass(); (void) llvm::createConstantMergePass(); (void) llvm::createConstantPropagationPass(); (void) llvm::createCorrelatedExpressionEliminationPass(); @@ -76,17 +68,15 @@ (void) llvm::createIPSCCPPass(); (void) llvm::createIndVarSimplifyPass(); (void) llvm::createInstructionCombiningPass(); - (void) llvm::createInternalizePass(); + (void) llvm::createInternalizePass(false); (void) llvm::createLICMPass(); (void) llvm::createLoadValueNumberingPass(); (void) llvm::createLoopExtractorPass(); - (void) llvm::createLoopInstrumentationPass(); (void) llvm::createLoopSimplifyPass(); (void) llvm::createLoopStrengthReducePass(); (void) llvm::createLoopUnrollPass(); (void) llvm::createLoopUnswitchPass(); (void) llvm::createLowerAllocationsPass(); - (void) llvm::createLowerConstantExpressionsPass(); (void) llvm::createLowerGCPass(); (void) llvm::createLowerInvokePass(); (void) llvm::createLowerFixedVectorPass(); @@ -97,8 +87,8 @@ (void) llvm::createNoProfileInfoPass(); (void) llvm::createPREPass(); (void) llvm::createProfileLoaderPass(); - (void) llvm::createProfilePathsPass(); (void) llvm::createPromoteMemoryToRegisterPass(); + (void) llvm::createDemoteRegisterToMemoryPass(); (void) llvm::createPruneEHPass(); (void) llvm::createRaiseAllocationsPass(); (void) llvm::createRaisePointerReferencesPass(); @@ -116,10 +106,13 @@ (void) llvm::createTraceValuesPassForFunction(); (void) llvm::createUnifyFunctionExitNodesPass(); (void) llvm::createCondPropagationPass(); + (void) llvm::createRaiseVectorsPass(); + (void) llvm::createLowerVectorsPass(); + (void) llvm::createAlloca2ReallocPass(); + (void) llvm::createAltiVecPass(); + (void) llvm::createSSEPass(); } - } _ForcePassLinking; + } ForcePassLinking; }; -#endif // _MSC_VER - #endif Index: llvm/include/llvm/Transforms/Scalar.h diff -u llvm/include/llvm/Transforms/Scalar.h:1.56.4.1 llvm/include/llvm/Transforms/Scalar.h:1.56.4.2 --- llvm/include/llvm/Transforms/Scalar.h:1.56.4.1 Tue Oct 18 14:21:56 2005 +++ llvm/include/llvm/Transforms/Scalar.h Wed Nov 16 12:32:00 2005 @@ -162,6 +162,12 @@ // FunctionPass *createPromoteMemoryToRegisterPass(); +//===----------------------------------------------------------------------===// +// +// This pass is used to demote registers to memory references . +// In basically undoes the PromoteMemoryToRegister pass to +// make cfg hacking easier. +FunctionPass *createDemoteRegisterToMemoryPass(); //===----------------------------------------------------------------------===// // @@ -271,7 +277,8 @@ // "my LLVM-to-LLVM pass doesn't support the invoke instruction yet" lowering // pass. // -FunctionPass *createLowerInvokePass(); +FunctionPass *createLowerInvokePass(unsigned JumBufSize = 200, + unsigned JumpBufAlign = 0); extern const PassInfo *LowerInvokePassID; @@ -282,11 +289,6 @@ FunctionPass *createLowerGCPass(); //===----------------------------------------------------------------------===// -// Returns a pass which converts all instances of ConstantExpression -// into regular LLVM instructions. -FunctionPass* createLowerConstantExpressionsPass(); - -//===----------------------------------------------------------------------===// // This pass reorders basic blocks in order to increase the number of fall- // through conditional branches. FunctionPass *createBlockPlacementPass(); @@ -295,6 +297,13 @@ // This pass does partial redundancy elimination. FunctionPass *createPREPass(); +// Vector stuff +FunctionPass *createRaiseVectorsPass(); +FunctionPass *createLowerVectorsPass(); +FunctionPass *createAlloca2ReallocPass(); +FunctionPass *createAltiVecPass(); +FunctionPass *createSSEPass(); + } // End llvm namespace #endif From bocchino at cs.uiuc.edu Wed Nov 16 12:32:13 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:13 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/include/llvm/Transforms/Utils/Local.h Message-ID: <200511161832.MAA20762@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms/Utils: Local.h updated: 1.21 -> 1.21.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+1 -8) Local.h | 9 +-------- 1 files changed, 1 insertion(+), 8 deletions(-) Index: llvm/include/llvm/Transforms/Utils/Local.h diff -u llvm/include/llvm/Transforms/Utils/Local.h:1.21 llvm/include/llvm/Transforms/Utils/Local.h:1.21.2.1 --- llvm/include/llvm/Transforms/Utils/Local.h:1.21 Tue Sep 27 14:38:43 2005 +++ llvm/include/llvm/Transforms/Utils/Local.h Wed Nov 16 12:32:01 2005 @@ -16,6 +16,7 @@ #define LLVM_TRANSFORMS_UTILS_LOCAL_H #include "llvm/Function.h" +#include "llvm/Analysis/ConstantFolding.h" namespace llvm { @@ -48,14 +49,6 @@ Constant *ConstantFoldInstruction(Instruction *I); -/// canConstantFoldCallTo - Return true if its even possible to fold a call to -/// the specified function. -bool canConstantFoldCallTo(Function *F); - -/// ConstantFoldCall - Attempt to constant fold a call to the specified function -/// with the specified arguments, returning null if unsuccessful. -Constant *ConstantFoldCall(Function *F, const std::vector &Operands); - /// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a /// getelementptr constantexpr, return the constant value being addressed by the /// constant expression, or null if something is funny and we can't decide. From bocchino at cs.uiuc.edu Wed Nov 16 12:32:14 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:14 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Analysis/ConstantFolding.cpp Expressions.cpp InstCount.cpp ScalarEvolution.cpp ScalarEvolutionExpander.cpp Message-ID: <200511161832.MAA20781@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ConstantFolding.cpp added (r1.1.4.2) Expressions.cpp (r1.45) removed InstCount.cpp updated: 1.12 -> 1.12.4.1 ScalarEvolution.cpp updated: 1.43.2.1 -> 1.43.2.2 ScalarEvolutionExpander.cpp updated: 1.1 -> 1.1.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+202 -2) ConstantFolding.cpp | 172 ++++++++++++++++++++++++++++++++++++++++++++ InstCount.cpp | 3 ScalarEvolution.cpp | 2 ScalarEvolutionExpander.cpp | 27 ++++++ 4 files changed, 202 insertions(+), 2 deletions(-) Index: llvm/lib/Analysis/ConstantFolding.cpp diff -c /dev/null llvm/lib/Analysis/ConstantFolding.cpp:1.1.4.2 *** /dev/null Wed Nov 16 12:32:13 2005 --- llvm/lib/Analysis/ConstantFolding.cpp Wed Nov 16 12:32:03 2005 *************** *** 0 **** --- 1,172 ---- + //===-- ConstantFolding.cpp - Analyze constant folding possibilities ------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This family of functions determines the possibility of performing constant + // folding. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Analysis/ConstantFolding.h" + #include "llvm/Constants.h" + #include "llvm/DerivedTypes.h" + #include "llvm/Instructions.h" + #include "llvm/Intrinsics.h" + #include "llvm/Support/GetElementPtrTypeIterator.h" + #include "llvm/Support/MathExtras.h" + #include + #include + using namespace llvm; + + //===----------------------------------------------------------------------===// + // Constant Folding ... + // + + + /// canConstantFoldCallTo - Return true if its even possible to fold a call to + /// the specified function. + bool + llvm::canConstantFoldCallTo(Function *F) { + const std::string &Name = F->getName(); + + switch (F->getIntrinsicID()) { + case Intrinsic::isunordered: + case Intrinsic::sqrt: + return true; + default: break; + } + + switch (Name[0]) + { + case 'a': + return Name == "acos" || Name == "asin" || Name == "atan" || + Name == "atan2"; + case 'c': + return Name == "ceil" || Name == "cos" || Name == "cosf" || + Name == "cosh"; + case 'e': + return Name == "exp"; + case 'f': + return Name == "fabs" || Name == "fmod" || Name == "floor"; + case 'l': + return Name == "log" || Name == "log10"; + case 'p': + return Name == "pow"; + case 's': + return Name == "sin" || Name == "sinh" || Name == "sqrt"; + case 't': + return Name == "tan" || Name == "tanh"; + default: + return false; + } + } + + Constant * + llvm::ConstantFoldFP(double (*NativeFP)(double), double V, const Type *Ty) { + errno = 0; + V = NativeFP(V); + if (errno == 0) + return ConstantFP::get(Ty, V); + return 0; + } + + /// ConstantFoldCall - Attempt to constant fold a call to the specified function + /// with the specified arguments, returning null if unsuccessful. + Constant * + llvm::ConstantFoldCall(Function *F, const std::vector &Operands) { + const std::string &Name = F->getName(); + const Type *Ty = F->getReturnType(); + + if (Operands.size() == 1) { + if (ConstantFP *Op = dyn_cast(Operands[0])) { + double V = Op->getValue(); + switch (Name[0]) + { + case 'a': + if (Name == "acos") + return ConstantFoldFP(acos, V, Ty); + else if (Name == "asin") + return ConstantFoldFP(asin, V, Ty); + else if (Name == "atan") + return ConstantFP::get(Ty, atan(V)); + break; + case 'c': + if (Name == "ceil") + return ConstantFoldFP(ceil, V, Ty); + else if (Name == "cos") + return ConstantFP::get(Ty, cos(V)); + else if (Name == "cosh") + return ConstantFP::get(Ty, cosh(V)); + break; + case 'e': + if (Name == "exp") + return ConstantFP::get(Ty, exp(V)); + break; + case 'f': + if (Name == "fabs") + return ConstantFP::get(Ty, fabs(V)); + else if (Name == "floor") + return ConstantFoldFP(floor, V, Ty); + break; + case 'l': + if (Name == "log" && V > 0) + return ConstantFP::get(Ty, log(V)); + else if (Name == "log10" && V > 0) + return ConstantFoldFP(log10, V, Ty); + else if (Name == "llvm.sqrt") { + if (V >= -0.0) + return ConstantFP::get(Ty, sqrt(V)); + else // Undefined + return ConstantFP::get(Ty, 0.0); + } + break; + case 's': + if (Name == "sin") + return ConstantFP::get(Ty, sin(V)); + else if (Name == "sinh") + return ConstantFP::get(Ty, sinh(V)); + else if (Name == "sqrt" && V >= 0) + return ConstantFP::get(Ty, sqrt(V)); + break; + case 't': + if (Name == "tan") + return ConstantFP::get(Ty, tan(V)); + else if (Name == "tanh") + return ConstantFP::get(Ty, tanh(V)); + break; + default: + break; + } + } + } else if (Operands.size() == 2) { + if (ConstantFP *Op1 = dyn_cast(Operands[0])) { + double Op1V = Op1->getValue(); + if (ConstantFP *Op2 = dyn_cast(Operands[1])) { + double Op2V = Op2->getValue(); + + if (Name == "llvm.isunordered") + return ConstantBool::get(IsNAN(Op1V) || IsNAN(Op2V)); + else + if (Name == "pow") { + errno = 0; + double V = pow(Op1V, Op2V); + if (errno == 0) + return ConstantFP::get(Ty, V); + } else if (Name == "fmod") { + errno = 0; + double V = fmod(Op1V, Op2V); + if (errno == 0) + return ConstantFP::get(Ty, V); + } else if (Name == "atan2") + return ConstantFP::get(Ty, atan2(Op1V,Op2V)); + } + } + } + return 0; + } + Index: llvm/lib/Analysis/InstCount.cpp diff -u llvm/lib/Analysis/InstCount.cpp:1.12 llvm/lib/Analysis/InstCount.cpp:1.12.4.1 --- llvm/lib/Analysis/InstCount.cpp:1.12 Thu Apr 21 16:04:58 2005 +++ llvm/lib/Analysis/InstCount.cpp Wed Nov 16 12:32:03 2005 @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Analysis/Passes.h" #include "llvm/Pass.h" #include "llvm/Function.h" #include "llvm/Support/InstVisitor.h" @@ -57,6 +58,8 @@ "Counts the various types of Instructions"); } +FunctionPass *llvm::createInstCountPass() { return new InstCount(); } + // InstCount::run - This is the main Analysis entry point for a // function. // Index: llvm/lib/Analysis/ScalarEvolution.cpp diff -u llvm/lib/Analysis/ScalarEvolution.cpp:1.43.2.1 llvm/lib/Analysis/ScalarEvolution.cpp:1.43.2.2 --- llvm/lib/Analysis/ScalarEvolution.cpp:1.43.2.1 Tue Oct 18 14:21:56 2005 +++ llvm/lib/Analysis/ScalarEvolution.cpp Wed Nov 16 12:32:03 2005 @@ -64,10 +64,10 @@ #include "llvm/DerivedTypes.h" #include "llvm/GlobalVariable.h" #include "llvm/Instructions.h" +#include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Assembly/Writer.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/Support/CFG.h" #include "llvm/Support/ConstantRange.h" #include "llvm/Support/InstIterator.h" Index: llvm/lib/Analysis/ScalarEvolutionExpander.cpp diff -u llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.1 llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.1.2.1 --- llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.1 Fri Jul 29 19:12:19 2005 +++ llvm/lib/Analysis/ScalarEvolutionExpander.cpp Wed Nov 16 12:32:03 2005 @@ -87,9 +87,34 @@ // Get the canonical induction variable I for this loop. Value *I = getOrInsertCanonicalInductionVariable(L, Ty); + // If this is a simple linear addrec, emit it now as a special case. if (S->getNumOperands() == 2) { // {0,+,F} --> i*F Value *F = expandInTy(S->getOperand(1), Ty); - return BinaryOperator::createMul(I, F, "tmp.", InsertPt); + + // IF the step is by one, just return the inserted IV. + if (ConstantIntegral *CI = dyn_cast(F)) + if (CI->getRawValue() == 1) + return I; + + // If the insert point is directly inside of the loop, emit the multiply at + // the insert point. Otherwise, L is a loop that is a parent of the insert + // point loop. If we can, move the multiply to the outer most loop that it + // is safe to be in. + Instruction *MulInsertPt = InsertPt; + Loop *InsertPtLoop = LI.getLoopFor(MulInsertPt->getParent()); + if (InsertPtLoop != L && InsertPtLoop && + L->contains(InsertPtLoop->getHeader())) { + while (InsertPtLoop != L) { + // If we cannot hoist the multiply out of this loop, don't. + if (!InsertPtLoop->isLoopInvariant(F)) break; + + // Otherwise, move the insert point to the preheader of the loop. + MulInsertPt = InsertPtLoop->getLoopPreheader()->getTerminator(); + InsertPtLoop = InsertPtLoop->getParentLoop(); + } + } + + return BinaryOperator::createMul(I, F, "tmp.", MulInsertPt); } // If this is a chain of recurrences, turn it into a closed form, using the From bocchino at cs.uiuc.edu Wed Nov 16 12:32:15 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:15 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Analysis/DataStructure/DataStructureStats.cpp GraphChecker.cpp Makefile Message-ID: <200511161832.MAA20792@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructureStats.cpp updated: 1.18 -> 1.18.4.1 GraphChecker.cpp updated: 1.18 -> 1.18.4.1 Makefile updated: 1.4 -> 1.4.6.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+11 -1) DataStructureStats.cpp | 5 +++++ GraphChecker.cpp | 5 +++++ Makefile | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) Index: llvm/lib/Analysis/DataStructure/DataStructureStats.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructureStats.cpp:1.18 llvm/lib/Analysis/DataStructure/DataStructureStats.cpp:1.18.4.1 --- llvm/lib/Analysis/DataStructure/DataStructureStats.cpp:1.18 Thu Apr 21 16:07:28 2005 +++ llvm/lib/Analysis/DataStructure/DataStructureStats.cpp Wed Nov 16 12:32:04 2005 @@ -63,6 +63,11 @@ static RegisterAnalysis Z("dsstats", "DS Graph Statistics"); } +FunctionPass *llvm::createDataStructureStatsPass() { + return new DSGraphStats(); +} + + static bool isIndirectCallee(Value *V) { if (isa(V)) return false; Index: llvm/lib/Analysis/DataStructure/GraphChecker.cpp diff -u llvm/lib/Analysis/DataStructure/GraphChecker.cpp:1.18 llvm/lib/Analysis/DataStructure/GraphChecker.cpp:1.18.4.1 --- llvm/lib/Analysis/DataStructure/GraphChecker.cpp:1.18 Thu Apr 21 16:07:28 2005 +++ llvm/lib/Analysis/DataStructure/GraphChecker.cpp Wed Nov 16 12:32:04 2005 @@ -77,6 +77,11 @@ RegisterAnalysis X("datastructure-gc", "DSA Graph Checking Pass"); } +FunctionPass *llvm::createDataStructureGraphCheckerPass() { + return new DSGC(); +} + + DSGC::DSGC() { if (!AbortIfAnyCollapsed && AbortIfCollapsed.empty() && CheckFlags.empty() && AbortIfMerged.empty()) { Index: llvm/lib/Analysis/DataStructure/Makefile diff -u llvm/lib/Analysis/DataStructure/Makefile:1.4 llvm/lib/Analysis/DataStructure/Makefile:1.4.6.1 --- llvm/lib/Analysis/DataStructure/Makefile:1.4 Thu Oct 28 00:36:48 2004 +++ llvm/lib/Analysis/DataStructure/Makefile Wed Nov 16 12:32:04 2005 @@ -6,9 +6,9 @@ # the University of Illinois Open Source License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## + LEVEL = ../../.. LIBRARYNAME = LLVMDataStructure -BUILD_ARCHIVE = 1 include $(LEVEL)/Makefile.common From bocchino at cs.uiuc.edu Wed Nov 16 12:32:19 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:19 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Analysis/IPA/FindUnsafePointerTypes.cpp Makefile PrintSCC.cpp Message-ID: <200511161832.MAA20809@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: FindUnsafePointerTypes.cpp (r1.28) removed Makefile updated: 1.4 -> 1.4.6.1 PrintSCC.cpp (r1.14) removed --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Analysis/IPA/Makefile diff -u llvm/lib/Analysis/IPA/Makefile:1.4 llvm/lib/Analysis/IPA/Makefile:1.4.6.1 --- llvm/lib/Analysis/IPA/Makefile:1.4 Thu Oct 28 00:36:47 2004 +++ llvm/lib/Analysis/IPA/Makefile Wed Nov 16 12:32:06 2005 @@ -6,9 +6,9 @@ # the University of Illinois Open Source License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## + LEVEL = ../../.. LIBRARYNAME = LLVMipa BUILD_ARCHIVE = 1 - include $(LEVEL)/Makefile.common From bocchino at cs.uiuc.edu Wed Nov 16 12:32:21 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:21 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Bytecode/Archive/Makefile Message-ID: <200511161832.MAA20831@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Archive: Makefile updated: 1.1 -> 1.1.6.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+0 -1) Makefile | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/Bytecode/Archive/Makefile diff -u llvm/lib/Bytecode/Archive/Makefile:1.1 llvm/lib/Bytecode/Archive/Makefile:1.1.6.1 --- llvm/lib/Bytecode/Archive/Makefile:1.1 Sat Nov 6 02:52:36 2004 +++ llvm/lib/Bytecode/Archive/Makefile Wed Nov 16 12:32:09 2005 @@ -13,6 +13,5 @@ # We only want an archive so only those modules actually used by a tool are # included. BUILD_ARCHIVE = 1 -DONT_BUILD_RELINKED = 1 include $(LEVEL)/Makefile.common From bocchino at cs.uiuc.edu Wed Nov 16 12:32:22 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:22 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Bytecode/Reader/Reader.cpp ReaderWrappers.cpp Message-ID: <200511161832.MAA20840@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Reader: Reader.cpp updated: 1.167.2.1 -> 1.167.2.2 ReaderWrappers.cpp updated: 1.51 -> 1.51.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+93 -38) Reader.cpp | 125 ++++++++++++++++++++++++++++++++++++++--------------- ReaderWrappers.cpp | 6 +- 2 files changed, 93 insertions(+), 38 deletions(-) Index: llvm/lib/Bytecode/Reader/Reader.cpp diff -u llvm/lib/Bytecode/Reader/Reader.cpp:1.167.2.1 llvm/lib/Bytecode/Reader/Reader.cpp:1.167.2.2 --- llvm/lib/Bytecode/Reader/Reader.cpp:1.167.2.1 Tue Oct 18 14:21:57 2005 +++ llvm/lib/Bytecode/Reader/Reader.cpp Wed Nov 16 12:32:10 2005 @@ -680,7 +680,8 @@ break; case 42: { //VANext_old const Type* ArgTy = getValue(iType, Oprnds[0])->getType(); - Function* NF = TheModule->getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0); + Function* NF = TheModule->getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, + (Type *)0); //b = vanext a, t -> //foo = alloca 1 of t @@ -700,7 +701,8 @@ } case 43: { //VAArg_old const Type* ArgTy = getValue(iType, Oprnds[0])->getType(); - Function* NF = TheModule->getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0); + Function* NF = TheModule->getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, + (Type *)0); //b = vaarg a, t -> //foo = alloca 1 of t @@ -915,27 +917,33 @@ if (CallingConv) cast(Result)->setCallingConv(CallingConv); break; } - case Instruction::Malloc: - if (Oprnds.size() > 2) + case Instruction::Malloc: { + unsigned Align = 0; + if (Oprnds.size() == 2) + Align = (1 << Oprnds[1]) >> 1; + else if (Oprnds.size() > 2) error("Invalid malloc instruction!"); if (!isa(InstTy)) error("Invalid malloc instruction!"); Result = new MallocInst(cast(InstTy)->getElementType(), - Oprnds.size() ? getValue(Type::UIntTyID, - Oprnds[0]) : 0); + getValue(Type::UIntTyID, Oprnds[0]), Align); break; + } - case Instruction::Alloca: - if (Oprnds.size() > 2) + case Instruction::Alloca: { + unsigned Align = 0; + if (Oprnds.size() == 2) + Align = (1 << Oprnds[1]) >> 1; + else if (Oprnds.size() > 2) error("Invalid alloca instruction!"); if (!isa(InstTy)) error("Invalid alloca instruction!"); Result = new AllocaInst(cast(InstTy)->getElementType(), - Oprnds.size() ? getValue(Type::UIntTyID, - Oprnds[0]) :0); + getValue(Type::UIntTyID, Oprnds[0]), Align); break; + } case Instruction::Free: if (!isa(InstTy)) error("Invalid free instruction!"); @@ -1985,6 +1993,10 @@ if (Handler) Handler->handleModuleGlobalsBegin(); + // SectionID - If a global has an explicit section specified, this map + // remembers the ID until we can translate it into a string. + std::map SectionID; + // Read global variables... unsigned VarType = read_vbr_uint(); while (VarType != Type::VoidTyID) { // List is terminated by Void @@ -1995,9 +2007,24 @@ error("Invalid type (type type) for global var!"); unsigned LinkageID = (VarType >> 2) & 7; bool isConstant = VarType & 1; - bool hasInitializer = VarType & 2; - GlobalValue::LinkageTypes Linkage; + bool hasInitializer = (VarType & 2) != 0; + unsigned Alignment = 0; + unsigned GlobalSectionID = 0; + + // An extension word is present when linkage = 3 (internal) and hasinit = 0. + if (LinkageID == 3 && !hasInitializer) { + unsigned ExtWord = read_vbr_uint(); + // The extension word has this format: bit 0 = has initializer, bit 1-3 = + // linkage, bit 4-8 = alignment (log2), bits 10+ = future use. + hasInitializer = ExtWord & 1; + LinkageID = (ExtWord >> 1) & 7; + Alignment = (1 << ((ExtWord >> 4) & 31)) >> 1; + + if (ExtWord & (1 << 9)) // Has a section ID. + GlobalSectionID = read_vbr_uint(); + } + GlobalValue::LinkageTypes Linkage; switch (LinkageID) { case 0: Linkage = GlobalValue::ExternalLinkage; break; case 1: Linkage = GlobalValue::WeakLinkage; break; @@ -2011,21 +2038,23 @@ } const Type *Ty = getType(SlotNo); - if (!Ty) { + if (!Ty) error("Global has no type! SlotNo=" + utostr(SlotNo)); - } - if (!isa(Ty)) { + if (!isa(Ty)) error("Global not a pointer type! Ty= " + Ty->getDescription()); - } const Type *ElTy = cast(Ty)->getElementType(); // Create the global variable... GlobalVariable *GV = new GlobalVariable(ElTy, isConstant, Linkage, 0, "", TheModule); + GV->setAlignment(Alignment); insertValue(GV, SlotNo, ModuleValues); + if (GlobalSectionID != 0) + SectionID[GV] = GlobalSectionID; + unsigned initSlot = 0; if (hasInitializer) { initSlot = read_vbr_uint(); @@ -2047,8 +2076,8 @@ FnSignature = (FnSignature << 5) + 1; // List is terminated by VoidTy. - while ((FnSignature >> 5) != Type::VoidTyID) { - const Type *Ty = getType(FnSignature >> 5); + while (((FnSignature & (~0U >> 1)) >> 5) != Type::VoidTyID) { + const Type *Ty = getType((FnSignature & (~0U >> 1)) >> 5); if (!isa(Ty) || !isa(cast(Ty)->getElementType())) { error("Function not a pointer to function type! Ty = " + @@ -2059,11 +2088,10 @@ const FunctionType* FTy = cast(cast(Ty)->getElementType()); - // Insert the place holder. - Function* Func = new Function(FTy, GlobalValue::ExternalLinkage, + Function *Func = new Function(FTy, GlobalValue::ExternalLinkage, "", TheModule); - insertValue(Func, FnSignature >> 5, ModuleValues); + insertValue(Func, (FnSignature & (~0U >> 1)) >> 5, ModuleValues); // Flags are not used yet. unsigned Flags = FnSignature & 31; @@ -2074,13 +2102,20 @@ if ((Flags & (1 << 4)) == 0) FunctionSignatureList.push_back(Func); - // Look at the low bits. If there is a calling conv here, apply it, - // read it as a vbr. - Flags &= 15; - if (Flags) - Func->setCallingConv(Flags-1); - else - Func->setCallingConv(read_vbr_uint()); + // Get the calling convention from the low bits. + unsigned CC = Flags & 15; + unsigned Alignment = 0; + if (FnSignature & (1 << 31)) { // Has extension word? + unsigned ExtWord = read_vbr_uint(); + Alignment = (1 << (ExtWord & 31)) >> 1; + CC |= ((ExtWord >> 5) & 15) << 4; + + if (ExtWord & (1 << 10)) // Has a section ID. + SectionID[Func] = read_vbr_uint(); + } + + Func->setCallingConv(CC-1); + Func->setAlignment(Alignment); if (Handler) Handler->handleFunctionDeclaration(Func); @@ -2094,12 +2129,19 @@ // remove elements efficiently from the back of the vector. std::reverse(FunctionSignatureList.begin(), FunctionSignatureList.end()); - // If this bytecode format has dependent library information in it .. - if (!hasNoDependentLibraries) { - // Read in the number of dependent library items that follow + /// SectionNames - This contains the list of section names encoded in the + /// moduleinfoblock. Functions and globals with an explicit section index + /// into this to get their section name. + std::vector SectionNames; + + if (hasInconsistentModuleGlobalInfo) { + align32(); + } else if (!hasNoDependentLibraries) { + // If this bytecode format has dependent library information in it, read in + // the number of dependent library items that follow. unsigned num_dep_libs = read_vbr_uint(); std::string dep_lib; - while( num_dep_libs-- ) { + while (num_dep_libs--) { dep_lib = read_str(); TheModule->addLibrary(dep_lib); if (Handler) @@ -2107,15 +2149,28 @@ } - // Read target triple and place into the module + // Read target triple and place into the module. std::string triple = read_str(); TheModule->setTargetTriple(triple); if (Handler) Handler->handleTargetTriple(triple); + + if (At != BlockEnd && !hasAlignment) { + // If the file has section info in it, read the section names now. + unsigned NumSections = read_vbr_uint(); + while (NumSections--) + SectionNames.push_back(read_str()); + } } - if (hasInconsistentModuleGlobalInfo) - align32(); + // If any globals are in specified sections, assign them now. + for (std::map::iterator I = SectionID.begin(), E = + SectionID.end(); I != E; ++I) + if (I->second) { + if (I->second > SectionID.size()) + error("SectionID out of range for global!"); + I->first->setSection(SectionNames[I->second-1]); + } // This is for future proofing... in the future extra fields may be added that // we don't understand, so we transparently ignore them. Index: llvm/lib/Bytecode/Reader/ReaderWrappers.cpp diff -u llvm/lib/Bytecode/Reader/ReaderWrappers.cpp:1.51 llvm/lib/Bytecode/Reader/ReaderWrappers.cpp:1.51.2.1 --- llvm/lib/Bytecode/Reader/ReaderWrappers.cpp:1.51 Wed Jul 27 01:12:33 2005 +++ llvm/lib/Bytecode/Reader/ReaderWrappers.cpp Wed Nov 16 12:32:10 2005 @@ -181,7 +181,7 @@ const Type* ArgTy = F->getFunctionType()->getReturnType(); const Type* ArgTyPtr = PointerType::get(ArgTy); Function* NF = M->getOrInsertFunction("llvm.va_start", - RetTy, ArgTyPtr, 0); + RetTy, ArgTyPtr, (Type *)0); for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;) if (CallInst* CI = dyn_cast(*I++)) { @@ -204,7 +204,7 @@ const Type* ArgTy = F->getFunctionType()->getParamType(0); const Type* ArgTyPtr = PointerType::get(ArgTy); Function* NF = M->getOrInsertFunction("llvm.va_end", - RetTy, ArgTyPtr, 0); + RetTy, ArgTyPtr, (Type *)0); for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;) if (CallInst* CI = dyn_cast(*I++)) { @@ -230,7 +230,7 @@ const Type* ArgTy = F->getFunctionType()->getReturnType(); const Type* ArgTyPtr = PointerType::get(ArgTy); Function* NF = M->getOrInsertFunction("llvm.va_copy", - RetTy, ArgTyPtr, ArgTyPtr, 0); + RetTy, ArgTyPtr, ArgTyPtr, (Type *)0); for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;) if (CallInst* CI = dyn_cast(*I++)) { From bocchino at cs.uiuc.edu Wed Nov 16 12:32:24 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:24 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Bytecode/Writer/Writer.cpp WriterInternals.h Message-ID: <200511161832.MAA20852@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Writer: Writer.cpp updated: 1.108.2.1 -> 1.108.2.2 WriterInternals.h updated: 1.25 -> 1.25.4.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+80 -20) Writer.cpp | 96 +++++++++++++++++++++++++++++++++++++++++++++--------- WriterInternals.h | 4 -- 2 files changed, 80 insertions(+), 20 deletions(-) Index: llvm/lib/Bytecode/Writer/Writer.cpp diff -u llvm/lib/Bytecode/Writer/Writer.cpp:1.108.2.1 llvm/lib/Bytecode/Writer/Writer.cpp:1.108.2.2 --- llvm/lib/Bytecode/Writer/Writer.cpp:1.108.2.1 Tue Oct 18 14:21:57 2005 +++ llvm/lib/Bytecode/Writer/Writer.cpp Wed Nov 16 12:32:12 2005 @@ -161,8 +161,8 @@ Out.push_back( static_cast( (i >> 56) & 0xFF)); } -inline BytecodeBlock::BytecodeBlock(unsigned ID, BytecodeWriter& w, - bool elideIfEmpty, bool hasLongFormat ) +inline BytecodeBlock::BytecodeBlock(unsigned ID, BytecodeWriter &w, + bool elideIfEmpty, bool hasLongFormat) : Id(ID), Writer(w), ElideIfEmpty(elideIfEmpty), HasLongFormat(hasLongFormat){ if (HasLongFormat) { @@ -424,7 +424,6 @@ //===----------------------------------------------------------------------===// //=== Instruction Output ===// //===----------------------------------------------------------------------===// -typedef unsigned char uchar; // outputInstructionFormat0 - Output those weird instructions that have a large // number of operands or have large operands themselves. @@ -708,6 +707,13 @@ assert(Slots[1] != ~0U && "Cast return type unknown?"); if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1]; NumOperands++; + } else if (const AllocationInst *AI = dyn_cast(&I)) { + assert(NumOperands == 1 && "Bogus allocation!"); + if (AI->getAlignment()) { + Slots[1] = Log2_32(AI->getAlignment())+1; + if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1]; + NumOperands = 2; + } } else if (const GetElementPtrInst *GEP = dyn_cast(&I)) { // We need to encode the type of sequential type indices into their slot # unsigned Idx = 1; @@ -931,17 +937,53 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) { BytecodeBlock ModuleInfoBlock(BytecodeFormat::ModuleGlobalInfoBlockID, *this); + // Give numbers to sections as we encounter them. + unsigned SectionIDCounter = 0; + std::vector SectionNames; + std::map SectionID; + // Output the types for the global variables in the module... for (Module::const_global_iterator I = M->global_begin(), - End = M->global_end(); I != End;++I) { + End = M->global_end(); I != End; ++I) { int Slot = Table.getSlot(I->getType()); assert(Slot != -1 && "Module global vars is broken!"); + assert((I->hasInitializer() || !I->hasInternalLinkage()) && + "Global must have an initializer or have external linkage!"); + // Fields: bit0 = isConstant, bit1 = hasInitializer, bit2-4=Linkage, - // bit5+ = Slot # for type - unsigned oSlot = ((unsigned)Slot << 5) | (getEncodedLinkage(I) << 2) | - (I->hasInitializer() << 1) | (unsigned)I->isConstant(); - output_vbr(oSlot); + // bit5+ = Slot # for type. + bool HasExtensionWord = (I->getAlignment() != 0) || I->hasSection(); + + // If we need to use the extension byte, set linkage=3(internal) and + // initializer = 0 (impossible!). + if (!HasExtensionWord) { + unsigned oSlot = ((unsigned)Slot << 5) | (getEncodedLinkage(I) << 2) | + (I->hasInitializer() << 1) | (unsigned)I->isConstant(); + output_vbr(oSlot); + } else { + unsigned oSlot = ((unsigned)Slot << 5) | (3 << 2) | + (0 << 1) | (unsigned)I->isConstant(); + output_vbr(oSlot); + + // The extension word has this format: bit 0 = has initializer, bit 1-3 = + // linkage, bit 4-8 = alignment (log2), bit 9 = has SectionID, + // bits 10+ = future use. + unsigned ExtWord = (unsigned)I->hasInitializer() | + (getEncodedLinkage(I) << 1) | + ((Log2_32(I->getAlignment())+1) << 4) | + ((unsigned)I->hasSection() << 9); + output_vbr(ExtWord); + if (I->hasSection()) { + // Give section names unique ID's. + unsigned &Entry = SectionID[I->getSection()]; + if (Entry == 0) { + Entry = ++SectionIDCounter; + SectionNames.push_back(I->getSection()); + } + output_vbr(Entry); + } + } // If we have an initializer, output it now. if (I->hasInitializer()) { @@ -957,18 +999,35 @@ int Slot = Table.getSlot(I->getType()); assert(Slot != -1 && "Module slot calculator is broken!"); assert(Slot >= Type::FirstDerivedTyID && "Derived type not in range!"); - assert(((Slot << 5) >> 5) == Slot && "Slot # too big!"); - unsigned ID = (Slot << 5); - - if (I->getCallingConv() < 15) - ID += I->getCallingConv()+1; + assert(((Slot << 6) >> 6) == Slot && "Slot # too big!"); + unsigned CC = I->getCallingConv()+1; + unsigned ID = (Slot << 5) | (CC & 15); if (I->isExternal()) // If external, we don't have an FunctionInfo block. ID |= 1 << 4; + + if (I->getAlignment() || I->hasSection() || (CC & ~15) != 0) + ID |= 1 << 31; // Do we need an extension word? + output_vbr(ID); - - if (I->getCallingConv() >= 15) - output_vbr(I->getCallingConv()); + + if (ID & (1 << 31)) { + // Extension byte: bits 0-4 = alignment, bits 5-9 = top nibble of calling + // convention, bit 10 = hasSectionID. + ID = (Log2_32(I->getAlignment())+1) | ((CC >> 4) << 5) | + (I->hasSection() << 10); + output_vbr(ID); + + // Give section names unique ID's. + if (I->hasSection()) { + unsigned &Entry = SectionID[I->getSection()]; + if (Entry == 0) { + Entry = ++SectionIDCounter; + SectionNames.push_back(I->getSection()); + } + output_vbr(Entry); + } + } } output_vbr((unsigned)Table.getSlot(Type::VoidTy) << 5); @@ -981,6 +1040,11 @@ // Output the target triple from the module output(M->getTargetTriple()); + + // Emit the table of section names. + output_vbr((unsigned)SectionNames.size()); + for (unsigned i = 0, e = SectionNames.size(); i != e; ++i) + output(SectionNames[i]); } void BytecodeWriter::outputInstructions(const Function *F) { Index: llvm/lib/Bytecode/Writer/WriterInternals.h diff -u llvm/lib/Bytecode/Writer/WriterInternals.h:1.25 llvm/lib/Bytecode/Writer/WriterInternals.h:1.25.4.1 --- llvm/lib/Bytecode/Writer/WriterInternals.h:1.25 Thu Apr 21 16:48:46 2005 +++ llvm/lib/Bytecode/Writer/WriterInternals.h Wed Nov 16 12:32:12 2005 @@ -10,10 +10,6 @@ // This header defines the interface used between components of the bytecode // writer. // -// Note that the performance of this library is not terribly important, because -// it shouldn't be used by JIT type applications... so it is not a huge focus -// at least. :) -// //===----------------------------------------------------------------------===// #ifndef LLVM_LIB_BYTECODE_WRITER_WRITERINTERNALS_H From bocchino at cs.uiuc.edu Wed Nov 16 12:32:26 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:26 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/CodeGen/AsmPrinter.cpp ELFWriter.cpp IntrinsicLowering.cpp LiveInterval.cpp LiveIntervalAnalysis.cpp Passes.cpp PrologEpilogInserter.cpp RegAllocIterativeScan.cpp RegAllocLocal.cpp TwoAddressInstructionPass.cpp Message-ID: <200511161832.MAA20881@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.20 -> 1.20.2.1 ELFWriter.cpp updated: 1.15 -> 1.15.2.1 IntrinsicLowering.cpp updated: 1.34 -> 1.34.2.1 LiveInterval.cpp updated: 1.22 -> 1.22.2.1 LiveIntervalAnalysis.cpp updated: 1.149 -> 1.149.2.1 Passes.cpp updated: 1.15 -> 1.15.4.1 PrologEpilogInserter.cpp updated: 1.49 -> 1.49.2.1 RegAllocIterativeScan.cpp (r1.22) removed RegAllocLocal.cpp updated: 1.74 -> 1.74.2.1 TwoAddressInstructionPass.cpp updated: 1.30 -> 1.30.4.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+212 -76) AsmPrinter.cpp | 37 ++++++++----- ELFWriter.cpp | 1 IntrinsicLowering.cpp | 9 ++- LiveInterval.cpp | 86 +++++++++++++++++++++++++------ LiveIntervalAnalysis.cpp | 115 +++++++++++++++++++++++++++++++----------- Passes.cpp | 5 - PrologEpilogInserter.cpp | 13 +++- RegAllocLocal.cpp | 18 ++++-- TwoAddressInstructionPass.cpp | 4 - 9 files changed, 212 insertions(+), 76 deletions(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.20 llvm/lib/CodeGen/AsmPrinter.cpp:1.20.2.1 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.20 Wed Aug 17 14:24:40 2005 +++ llvm/lib/CodeGen/AsmPrinter.cpp Wed Nov 16 12:32:14 2005 @@ -13,7 +13,7 @@ #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/Constants.h" -#include "llvm/Instruction.h" +#include "llvm/Module.h" #include "llvm/Support/Mangler.h" #include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetMachine.h" @@ -31,11 +31,14 @@ void AsmPrinter::setupMachineFunction(MachineFunction &MF) { // What's my mangled name? - CurrentFnName = Mang->getValueName((Value*)MF.getFunction()); + CurrentFnName = Mang->getValueName(MF.getFunction()); } // emitAlignment - Emit an alignment directive to the specified power of two. -void AsmPrinter::emitAlignment(unsigned NumBits) const { +void AsmPrinter::emitAlignment(unsigned NumBits, const GlobalValue *GV) const { + if (GV && GV->getAlignment()) + NumBits = Log2_32(GV->getAlignment()); + if (NumBits == 0) return; // No need to emit alignment. if (AlignmentIsInBytes) NumBits = 1 << NumBits; O << AlignDirective << NumBits << "\n"; } @@ -68,15 +71,15 @@ O << (uint64_t)CI->getValue(); else if (const ConstantUInt *CI = dyn_cast(CV)) O << CI->getValue(); - else if (isa((Value*)CV)) { + else if (const GlobalValue *GV = dyn_cast(CV)) { // This is a constant address for a global variable or function. Use the // name of the variable or function as the address value, possibly // decorating it with GlobalVarAddrPrefix/Suffix or // FunctionAddrPrefix/Suffix (these all default to "" ) - if (isa((Value*)CV)) - O << FunctionAddrPrefix << Mang->getValueName(CV) << FunctionAddrSuffix; + if (isa(GV)) + O << FunctionAddrPrefix << Mang->getValueName(GV) << FunctionAddrSuffix; else - O << GlobalVarAddrPrefix << Mang->getValueName(CV) << GlobalVarAddrSuffix; + O << GlobalVarAddrPrefix << Mang->getValueName(GV) << GlobalVarAddrSuffix; } else if (const ConstantExpr *CE = dyn_cast(CV)) { const TargetData &TD = TM.getTargetData(); switch(CE->getOpcode()) { @@ -115,9 +118,7 @@ || (((TD.getTypeSize(Ty) >= TD.getTypeSize(OpTy)) && OpTy->isLosslesslyConvertibleTo(Ty)))) && "FIXME: Don't yet support this kind of constant cast expr"); - O << "("; emitConstantValueOnly(Op); - O << ")"; break; } case Instruction::Add: @@ -141,14 +142,15 @@ return (X&7)+'0'; } -/// getAsCString - Return the specified array as a C compatible string, only if +/// printAsCString - Print the specified array as a C compatible string, only if /// the predicate isString is true. /// -static void printAsCString(std::ostream &O, const ConstantArray *CVA) { +static void printAsCString(std::ostream &O, const ConstantArray *CVA, + unsigned LastElt) { assert(CVA->isString() && "Array is not string compatible!"); O << "\""; - for (unsigned i = 0; i != CVA->getNumOperands(); ++i) { + for (unsigned i = 0; i != LastElt; ++i) { unsigned char C = (unsigned char)cast(CVA->getOperand(i))->getRawValue(); @@ -187,8 +189,15 @@ return; } else if (const ConstantArray *CVA = dyn_cast(CV)) { if (CVA->isString()) { - O << AsciiDirective; - printAsCString(O, CVA); + unsigned NumElts = CVA->getNumOperands(); + if (AscizDirective && NumElts && + cast(CVA->getOperand(NumElts-1))->getRawValue() == 0) { + O << AscizDirective; + printAsCString(O, CVA, NumElts-1); + } else { + O << AsciiDirective; + printAsCString(O, CVA, NumElts); + } O << "\n"; } else { // Not a string. Print the values in successive locations for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i) Index: llvm/lib/CodeGen/ELFWriter.cpp diff -u llvm/lib/CodeGen/ELFWriter.cpp:1.15 llvm/lib/CodeGen/ELFWriter.cpp:1.15.2.1 --- llvm/lib/CodeGen/ELFWriter.cpp:1.15 Fri Aug 19 11:19:21 2005 +++ llvm/lib/CodeGen/ELFWriter.cpp Wed Nov 16 12:32:14 2005 @@ -25,7 +25,6 @@ // #3. ".bss" entry - global variables without initializers. [ if needed ] // ... // #N. ".shstrtab" entry - String table for the section names. - // // NOTE: This code should eventually be extended to support 64-bit ELF (this // won't be hard), but we haven't done so yet! Index: llvm/lib/CodeGen/IntrinsicLowering.cpp diff -u llvm/lib/CodeGen/IntrinsicLowering.cpp:1.34 llvm/lib/CodeGen/IntrinsicLowering.cpp:1.34.2.1 --- llvm/lib/CodeGen/IntrinsicLowering.cpp:1.34 Wed Jul 27 01:12:33 2005 +++ llvm/lib/CodeGen/IntrinsicLowering.cpp Wed Nov 16 12:32:14 2005 @@ -110,7 +110,8 @@ case Intrinsic::memset: M.getOrInsertFunction("memset", PointerType::get(Type::SByteTy), PointerType::get(Type::SByteTy), - Type::IntTy, (--(--I->arg_end()))->getType(), 0); + Type::IntTy, (--(--I->arg_end()))->getType(), + (Type *)0); break; case Intrinsic::isunordered: EnsureFunctionExists(M, "isunordered", I->arg_begin(), I->arg_end(), @@ -261,6 +262,12 @@ case Intrinsic::pcmarker: break; // Simply strip out pcmarker on unsupported architectures + case Intrinsic::readcyclecounter: { + std::cerr << "WARNING: this target does not support the llvm.readcyclecounter" + << " intrinsic. It is being lowered to a constant 0\n"; + CI->replaceAllUsesWith(ConstantUInt::get(Type::ULongTy, 0)); + break; + } case Intrinsic::dbg_stoppoint: case Intrinsic::dbg_region_start: Index: llvm/lib/CodeGen/LiveInterval.cpp diff -u llvm/lib/CodeGen/LiveInterval.cpp:1.22 llvm/lib/CodeGen/LiveInterval.cpp:1.22.2.1 --- llvm/lib/CodeGen/LiveInterval.cpp:1.22 Tue Sep 20 23:19:08 2005 +++ llvm/lib/CodeGen/LiveInterval.cpp Wed Nov 16 12:32:14 2005 @@ -101,6 +101,27 @@ return false; } +/// NontrivialOverlap - Check to see if the two live ranges specified by i and j +/// overlap. If so, check to see if they have value numbers that are not +/// iIdx/jIdx respectively. If both conditions are true, return true. +static inline bool NontrivialOverlap(const LiveRange &I, const LiveRange &J, + unsigned iIdx, unsigned jIdx) { + if (I.start == J.start) { + // If this is not the allowed value merge, we cannot join. + if (I.ValId != iIdx || J.ValId != jIdx) + return true; + } else if (I.start < J.start) { + if (I.end > J.start && (I.ValId != iIdx || J.ValId != jIdx)) { + return true; + } + } else { + if (J.end > I.start && (I.ValId != iIdx || J.ValId != jIdx)) + return true; + } + + return false; +} + /// joinable - Two intervals are joinable if the either don't overlap at all /// or if the destination of the copy is a single assignment value, and it /// only overlaps with one value in the source interval. @@ -125,21 +146,9 @@ } while (i != ie && j != je) { - if (i->start == j->start) { - // If this is not the allowed value merge, we cannot join. - if (i->ValId != ThisValIdx || j->ValId != OtherValIdx) - return false; - } else if (i->start < j->start) { - if (i->end > j->start) { - if (i->ValId != ThisValIdx || j->ValId != OtherValIdx) - return false; - } - } else { - if (j->end > i->start) { - if (i->ValId != ThisValIdx || j->ValId != OtherValIdx) - return false; - } - } + if (NontrivialOverlap(*i, *j, ThisValIdx, OtherValIdx)) + return false; + if (i->end < j->end) ++i; else @@ -149,6 +158,43 @@ return true; } +/// getOverlapingRanges - Given another live interval which is defined as a +/// copy from this one, return a list of all of the live ranges where the +/// two overlap and have different value numbers. +void LiveInterval::getOverlapingRanges(const LiveInterval &other, + unsigned CopyIdx, + std::vector &Ranges) { + const LiveRange *SourceLR = getLiveRangeContaining(CopyIdx-1); + const LiveRange *DestLR = other.getLiveRangeContaining(CopyIdx); + assert(SourceLR && DestLR && "Not joining due to a copy?"); + unsigned OtherValIdx = SourceLR->ValId; + unsigned ThisValIdx = DestLR->ValId; + + Ranges::iterator i = ranges.begin(); + Ranges::iterator ie = ranges.end(); + Ranges::const_iterator j = other.ranges.begin(); + Ranges::const_iterator je = other.ranges.end(); + + if (i->start < j->start) { + i = std::upper_bound(i, ie, j->start); + if (i != ranges.begin()) --i; + } else if (j->start < i->start) { + j = std::upper_bound(j, je, i->start); + if (j != other.ranges.begin()) --j; + } + + while (i != ie && j != je) { + if (NontrivialOverlap(*i, *j, ThisValIdx, OtherValIdx)) + Ranges.push_back(&*i); + + if (i->end < j->end) + ++i; + else + ++j; + } +} + + /// extendIntervalEndTo - This method is used when we want to extend the range /// specified by I to end at the specified endpoint. To do this, we should @@ -167,8 +213,16 @@ // If NewEnd was in the middle of an interval, make sure to get its endpoint. I->end = std::max(NewEnd, prior(MergeTo)->end); - // Erase any dead ranges + // Erase any dead ranges. ranges.erase(next(I), MergeTo); + + // If the newly formed range now touches the range after it and if they have + // the same value number, merge the two ranges into one range. + Ranges::iterator Next = next(I); + if (Next != ranges.end() && Next->start <= I->end && Next->ValId == ValId) { + I->end = Next->end; + ranges.erase(Next); + } } Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.149 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.149.2.1 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.149 Tue Sep 20 23:19:09 2005 +++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Nov 16 12:32:14 2005 @@ -633,6 +633,49 @@ } } +/// IntA is defined as a copy from IntB and we know it only has one value +/// number. If all of the places that IntA and IntB overlap are defined by +/// copies from IntA to IntB, we know that these two ranges can really be +/// merged if we adjust the value numbers. If it is safe, adjust the value +/// numbers and return true, allowing coalescing to occur. +bool LiveIntervals:: +AdjustIfAllOverlappingRangesAreCopiesFrom(LiveInterval &IntA, + LiveInterval &IntB, + unsigned CopyIdx) { + std::vector Ranges; + IntA.getOverlapingRanges(IntB, CopyIdx, Ranges); + + assert(!Ranges.empty() && "Why didn't we do a simple join of this?"); + + unsigned IntBRep = rep(IntB.reg); + + // Check to see if all of the overlaps (entries in Ranges) are defined by a + // copy from IntA. If not, exit. + for (unsigned i = 0, e = Ranges.size(); i != e; ++i) { + unsigned Idx = Ranges[i]->start; + MachineInstr *MI = getInstructionFromIndex(Idx); + unsigned SrcReg, DestReg; + if (!tii_->isMoveInstr(*MI, SrcReg, DestReg)) return false; + + // If this copy isn't actually defining this range, it must be a live + // range spanning basic blocks or something. + if (rep(DestReg) != rep(IntA.reg)) return false; + + // Check to see if this is coming from IntB. If not, bail out. + if (rep(SrcReg) != IntBRep) return false; + } + + // Okay, we can change this one. Get the IntB value number that IntA is + // copied from. + unsigned ActualValNo = IntA.getLiveRangeContaining(CopyIdx-1)->ValId; + + // Change all of the value numbers to the same as what we IntA is copied from. + for (unsigned i = 0, e = Ranges.size(); i != e; ++i) + Ranges[i]->ValId = ActualValNo; + + return true; +} + void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) { DEBUG(std::cerr << ((Value*)MBB->getBasicBlock())->getName() << ":\n"); @@ -643,60 +686,72 @@ // we only join virtual registers with allocatable // physical registers since we do not have liveness information // on not allocatable physical registers - unsigned regA, regB; - if (tii_->isMoveInstr(*mi, regA, regB) && - (MRegisterInfo::isVirtualRegister(regA) || allocatableRegs_[regA]) && - (MRegisterInfo::isVirtualRegister(regB) || allocatableRegs_[regB])) { + unsigned SrcReg, DestReg; + if (tii_->isMoveInstr(*mi, SrcReg, DestReg) && + (MRegisterInfo::isVirtualRegister(SrcReg) || allocatableRegs_[SrcReg])&& + (MRegisterInfo::isVirtualRegister(DestReg)||allocatableRegs_[DestReg])){ // Get representative registers. - regA = rep(regA); - regB = rep(regB); + SrcReg = rep(SrcReg); + DestReg = rep(DestReg); // If they are already joined we continue. - if (regA == regB) + if (SrcReg == DestReg) continue; // If they are both physical registers, we cannot join them. - if (MRegisterInfo::isPhysicalRegister(regA) && - MRegisterInfo::isPhysicalRegister(regB)) + if (MRegisterInfo::isPhysicalRegister(SrcReg) && + MRegisterInfo::isPhysicalRegister(DestReg)) continue; // If they are not of the same register class, we cannot join them. - if (differingRegisterClasses(regA, regB)) + if (differingRegisterClasses(SrcReg, DestReg)) continue; - LiveInterval &IntA = getInterval(regA); - LiveInterval &IntB = getInterval(regB); - assert(IntA.reg == regA && IntB.reg == regB && + LiveInterval &SrcInt = getInterval(SrcReg); + LiveInterval &DestInt = getInterval(DestReg); + assert(SrcInt.reg == SrcReg && DestInt.reg == DestReg && "Register mapping is horribly broken!"); - DEBUG(std::cerr << "\t\tInspecting " << IntA << " and " << IntB << ": "); + DEBUG(std::cerr << "\t\tInspecting " << SrcInt << " and " << DestInt + << ": "); // If two intervals contain a single value and are joined by a copy, it // does not matter if the intervals overlap, they can always be joined. - bool TriviallyJoinable = - IntA.containsOneValue() && IntB.containsOneValue(); + bool Joinable = SrcInt.containsOneValue() && DestInt.containsOneValue(); unsigned MIDefIdx = getDefIndex(getInstructionIndex(mi)); - if ((TriviallyJoinable || IntB.joinable(IntA, MIDefIdx)) && - !overlapsAliases(&IntA, &IntB)) { - IntB.join(IntA, MIDefIdx); - DEBUG(std::cerr << "Joined. Result = " << IntB << "\n"); - - if (!MRegisterInfo::isPhysicalRegister(regA)) { - r2iMap_.erase(regA); - r2rMap_[regA] = regB; + + // If the intervals think that this is joinable, do so now. + if (!Joinable && DestInt.joinable(SrcInt, MIDefIdx)) + Joinable = true; + + // If DestInt is actually a copy from SrcInt (which we know) that is used + // to define another value of SrcInt, we can change the other range of + // SrcInt to be the value of the range that defines DestInt, allowing a + // coalesce. + if (!Joinable && DestInt.containsOneValue() && + AdjustIfAllOverlappingRangesAreCopiesFrom(SrcInt, DestInt, MIDefIdx)) + Joinable = true; + + if (!Joinable || overlapsAliases(&SrcInt, &DestInt)) { + DEBUG(std::cerr << "Interference!\n"); + } else { + DestInt.join(SrcInt, MIDefIdx); + DEBUG(std::cerr << "Joined. Result = " << DestInt << "\n"); + + if (!MRegisterInfo::isPhysicalRegister(SrcReg)) { + r2iMap_.erase(SrcReg); + r2rMap_[SrcReg] = DestReg; } else { // Otherwise merge the data structures the other way so we don't lose // the physreg information. - r2rMap_[regB] = regA; - IntB.reg = regA; - IntA.swap(IntB); - r2iMap_.erase(regB); + r2rMap_[DestReg] = SrcReg; + DestInt.reg = SrcReg; + SrcInt.swap(DestInt); + r2iMap_.erase(DestReg); } ++numJoins; - } else { - DEBUG(std::cerr << "Interference!\n"); } } } Index: llvm/lib/CodeGen/Passes.cpp diff -u llvm/lib/CodeGen/Passes.cpp:1.15 llvm/lib/CodeGen/Passes.cpp:1.15.4.1 --- llvm/lib/CodeGen/Passes.cpp:1.15 Thu Apr 21 17:33:33 2005 +++ llvm/lib/CodeGen/Passes.cpp Wed Nov 16 12:32:14 2005 @@ -18,7 +18,7 @@ using namespace llvm; namespace { - enum RegAllocName { simple, local, linearscan, iterativescan }; + enum RegAllocName { simple, local, linearscan }; cl::opt RegAlloc( @@ -29,7 +29,6 @@ clEnumVal(simple, " simple register allocator"), clEnumVal(local, " local register allocator"), clEnumVal(linearscan, " linear scan register allocator"), - clEnumVal(iterativescan, " iterative scan register allocator"), clEnumValEnd), cl::init(linearscan)); } @@ -45,8 +44,6 @@ return createLocalRegisterAllocator(); case linearscan: return createLinearScanRegisterAllocator(); - case iterativescan: - return createIterativeScanRegisterAllocator(); } } Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp diff -u llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.49 llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.49.2.1 --- llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.49 Fri Sep 30 12:19:22 2005 +++ llvm/lib/CodeGen/PrologEpilogInserter.cpp Wed Nov 16 12:32:14 2005 @@ -258,6 +258,7 @@ MachineFrameInfo *FFI = Fn.getFrameInfo(); unsigned StackAlignment = TFI.getStackAlignment(); + unsigned MaxAlign = 0; // Start at the beginning of the local area. // The Offset is the distance from the stack top in the direction @@ -295,9 +296,11 @@ Offset += FFI->getObjectSize(i); unsigned Align = FFI->getObjectAlignment(i); - assert(Align <= StackAlignment && "Cannot align stack object to higher " - "alignment boundary than the stack itself!"); - Offset = (Offset+Align-1)/Align*Align; // Adjust to Alignment boundary... + // If the alignment of this object is greater than that of the stack, then + // increase the stack alignment to match. + MaxAlign = std::max(MaxAlign, Align); + // Adjust to alignment boundary + Offset = (Offset+Align-1)/Align*Align; if (StackGrowsDown) { FFI->setObjectOffset(i, -Offset); // Set the computed offset @@ -315,6 +318,10 @@ // Set the final value of the stack pointer... FFI->setStackSize(Offset+TFI.getOffsetOfLocalArea()); + + // Remember the required stack alignment in case targets need it to perform + // dynamic stack alignment. + FFI->setMaxAlignment(MaxAlign); } Index: llvm/lib/CodeGen/RegAllocLocal.cpp diff -u llvm/lib/CodeGen/RegAllocLocal.cpp:1.74 llvm/lib/CodeGen/RegAllocLocal.cpp:1.74.2.1 --- llvm/lib/CodeGen/RegAllocLocal.cpp:1.74 Thu Sep 29 20:29:00 2005 +++ llvm/lib/CodeGen/RegAllocLocal.cpp Wed Nov 16 12:32:14 2005 @@ -488,9 +488,11 @@ void RA::AllocateBasicBlock(MachineBasicBlock &MBB) { // loop over each instruction - MachineBasicBlock::iterator MI = MBB.begin(); - for (; MI != MBB.end(); ++MI) { - const TargetInstrDescriptor &TID = TM->getInstrInfo()->get(MI->getOpcode()); + MachineBasicBlock::iterator MII = MBB.begin(); + const TargetInstrInfo &TII = *TM->getInstrInfo(); + while (MII != MBB.end()) { + MachineInstr *MI = MII++; + const TargetInstrDescriptor &TID = TII.get(MI->getOpcode()); DEBUG(std::cerr << "\nStarting RegAlloc of: " << *MI; std::cerr << " Regs have values: "; for (unsigned i = 0; i != RegInfo->getNumRegs(); ++i) @@ -621,9 +623,14 @@ removePhysReg(PhysReg); } } + + // Finally, if this is a noop copy instruction, zap it. + unsigned SrcReg, DstReg; + if (TII.isMoveInstr(*MI, SrcReg, DstReg) && SrcReg == DstReg) + MBB.erase(MI); } - MI = MBB.getFirstTerminator(); + MachineBasicBlock::iterator MI = MBB.getFirstTerminator(); // Spill all physical registers holding virtual registers now. for (unsigned i = 0, e = RegInfo->getNumRegs(); i != e; ++i) @@ -633,7 +640,8 @@ else removePhysReg(i); -#ifndef NDEBUG +#if 0 + // This checking code is very expensive. bool AllOk = true; for (unsigned i = MRegisterInfo::FirstVirtualRegister, e = MF->getSSARegMap()->getLastVirtReg(); i <= e; ++i) Index: llvm/lib/CodeGen/TwoAddressInstructionPass.cpp diff -u llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:1.30 llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:1.30.4.1 --- llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:1.30 Thu Apr 21 17:33:33 2005 +++ llvm/lib/CodeGen/TwoAddressInstructionPass.cpp Wed Nov 16 12:32:14 2005 @@ -46,7 +46,7 @@ Statistic<> NumTwoAddressInstrs("twoaddressinstruction", "Number of two-address instructions"); Statistic<> NumCommuted("twoaddressinstruction", - "Number of instructions commuted to coallesce"); + "Number of instructions commuted to coalesce"); Statistic<> NumConvertedTo3Addr("twoaddressinstruction", "Number of instructions promoted to 3-address"); @@ -127,7 +127,7 @@ // If this instruction is not the killing user of B, see if we can // rearrange the code to make it so. Making it the killing user will - // allow us to coallesce A and B together, eliminating the copy we are + // allow us to coalesce A and B together, eliminating the copy we are // about to insert. if (!LV.KillsRegister(mi, regB)) { const TargetInstrDescriptor &TID = TII.get(opcode); From bocchino at cs.uiuc.edu Wed Nov 16 12:32:29 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:29 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Debugger/UnixLocalInferiorProcess.cpp Message-ID: <200511161832.MAA20905@zion.cs.uiuc.edu> Changes in directory llvm/lib/Debugger: UnixLocalInferiorProcess.cpp updated: 1.8 -> 1.8.4.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+2 -1) UnixLocalInferiorProcess.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Debugger/UnixLocalInferiorProcess.cpp diff -u llvm/lib/Debugger/UnixLocalInferiorProcess.cpp:1.8 llvm/lib/Debugger/UnixLocalInferiorProcess.cpp:1.8.4.1 --- llvm/lib/Debugger/UnixLocalInferiorProcess.cpp:1.8 Thu Apr 21 17:36:21 2005 +++ llvm/lib/Debugger/UnixLocalInferiorProcess.cpp Wed Nov 16 12:32:17 2005 @@ -924,7 +924,8 @@ // If the program didn't explicitly call exit, call exit now, for the program. // This ensures that any atexit handlers get called correctly. - Function *Exit = M->getOrInsertFunction("exit", Type::VoidTy, Type::IntTy, 0); + Function *Exit = M->getOrInsertFunction("exit", Type::VoidTy, Type::IntTy, + (Type *)0); std::vector Args; GenericValue ResultGV; From bocchino at cs.uiuc.edu Wed Nov 16 12:32:30 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:30 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/ExecutionEngine/ExecutionEngine.cpp Message-ID: <200511161832.MAA20913@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine: ExecutionEngine.cpp updated: 1.71 -> 1.71.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+4 -1) ExecutionEngine.cpp | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/lib/ExecutionEngine/ExecutionEngine.cpp diff -u llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.71 llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.71.2.1 --- llvm/lib/ExecutionEngine/ExecutionEngine.cpp:1.71 Tue Jul 12 10:51:55 2005 +++ llvm/lib/ExecutionEngine/ExecutionEngine.cpp Wed Nov 16 12:32:19 2005 @@ -189,7 +189,10 @@ uint64_t Offset = TD->getIndexedOffset(CE->getOperand(0)->getType(), Indexes); - Result.LongVal += Offset; + if (getTargetData().getPointerSize() == 4) + Result.IntVal += Offset; + else + Result.LongVal += Offset; return Result; } case Instruction::Cast: { From bocchino at cs.uiuc.edu Wed Nov 16 12:32:32 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:32 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp Message-ID: <200511161832.MAA20923@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: TargetSelect.cpp updated: 1.9 -> 1.9.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+3 -3) TargetSelect.cpp | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp diff -u llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp:1.9 llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp:1.9.2.1 --- llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp:1.9 Fri Sep 2 14:27:43 2005 +++ llvm/lib/ExecutionEngine/JIT/TargetSelect.cpp Wed Nov 16 12:32:21 2005 @@ -26,15 +26,15 @@ static cl::opt MCPU("mcpu", - cl::desc("Target a specific cpu type (-mcpu=help for list of choices)"), + cl::desc("Target a specific cpu type (-mcpu=help for details)"), cl::value_desc("cpu-name"), cl::init("")); static cl::list MAttrs("mattr", cl::CommaSeparated, - cl::desc("Target specific attributes (-mattr=help for list of choices)"), - cl::value_desc("attr1,+attr2, ..., -attrN")); + cl::desc("Target specific attributes (-mattr=help for details)"), + cl::value_desc("a1,+a2,-a3,...")); /// create - Create an return a new JIT compiler if there is one available /// for the current target. Otherwise, return null. From bocchino at cs.uiuc.edu Wed Nov 16 12:32:34 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:34 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Linker/Makefile Message-ID: <200511161832.MAA20933@zion.cs.uiuc.edu> Changes in directory llvm/lib/Linker: Makefile updated: 1.2 -> 1.2.6.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+1 -1) Makefile | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Linker/Makefile diff -u llvm/lib/Linker/Makefile:1.2 llvm/lib/Linker/Makefile:1.2.6.1 --- llvm/lib/Linker/Makefile:1.2 Sun Nov 14 16:03:14 2004 +++ llvm/lib/Linker/Makefile Wed Nov 16 12:32:22 2005 @@ -6,10 +6,10 @@ # University of Illinois Open Source License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## + LEVEL = ../.. LIBRARYNAME = LLVMLinker BUILD_ARCHIVE := 1 -DONT_BUILD_RELINKED := 1 include $(LEVEL)/Makefile.common From bocchino at cs.uiuc.edu Wed Nov 16 12:32:35 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:35 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Support/Makefile Message-ID: <200511161832.MAA20946@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: Makefile updated: 1.8 -> 1.8.6.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+1 -0) Makefile | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Support/Makefile diff -u llvm/lib/Support/Makefile:1.8 llvm/lib/Support/Makefile:1.8.6.1 --- llvm/lib/Support/Makefile:1.8 Thu Nov 25 13:38:28 2004 +++ llvm/lib/Support/Makefile Wed Nov 16 12:32:24 2005 @@ -6,6 +6,7 @@ # the University of Illinois Open Source License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## + LEVEL = ../.. PARALLEL_DIRS=bzip2 LIBRARYNAME = LLVMSupport From bocchino at cs.uiuc.edu Wed Nov 16 12:32:37 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:37 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/System/Makefile Message-ID: <200511161832.MAA20953@zion.cs.uiuc.edu> Changes in directory llvm/lib/System: Makefile updated: 1.7 -> 1.7.4.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+1 -0) Makefile | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/System/Makefile diff -u llvm/lib/System/Makefile:1.7 llvm/lib/System/Makefile:1.7.4.1 --- llvm/lib/System/Makefile:1.7 Fri Jan 14 16:43:01 2005 +++ llvm/lib/System/Makefile Wed Nov 16 12:32:25 2005 @@ -6,6 +6,7 @@ # University of Illinois Open Source License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## + LEVEL = ../.. LIBRARYNAME = LLVMSystem BUILD_ARCHIVE = 1 From bocchino at cs.uiuc.edu Wed Nov 16 12:32:27 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:27 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp LegalizeDAG.cpp ScheduleDAG.cpp SelectionDAG.cpp SelectionDAGISel.cpp Message-ID: <200511161832.MAA20896@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.47 -> 1.47.2.1 LegalizeDAG.cpp updated: 1.201 -> 1.201.2.1 ScheduleDAG.cpp updated: 1.37 -> 1.37.2.1 SelectionDAG.cpp updated: 1.206 -> 1.206.2.1 SelectionDAGISel.cpp updated: 1.88.2.1 -> 1.88.2.2 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+1099 -552) DAGCombiner.cpp | 357 ++++++++++++++++++++++++++++++++- LegalizeDAG.cpp | 85 +++++-- ScheduleDAG.cpp | 544 ++++++++++++++++++++++++++++++--------------------- SelectionDAG.cpp | 210 ++++++++++++------- SelectionDAGISel.cpp | 455 +++++++++++++++++++++--------------------- 5 files changed, 1099 insertions(+), 552 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.47 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.47.2.1 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.47 Tue Oct 18 01:04:22 2005 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Nov 16 12:32:15 2005 @@ -180,6 +180,9 @@ SDOperand N3, ISD::CondCode CC); SDOperand SimplifySetCC(MVT::ValueType VT, SDOperand N0, SDOperand N1, ISD::CondCode Cond, bool foldBooleans = true); + + SDOperand BuildSDIV(SDNode *N); + SDOperand BuildUDIV(SDNode *N); public: DAGCombiner(SelectionDAG &D) : DAG(D), TLI(D.getTargetLoweringInfo()), AfterLegalize(false) {} @@ -189,6 +192,178 @@ }; } +struct ms { + int64_t m; // magic number + int64_t s; // shift amount +}; + +struct mu { + uint64_t m; // magic number + int64_t a; // add indicator + int64_t s; // shift amount +}; + +/// magic - calculate the magic numbers required to codegen an integer sdiv as +/// a sequence of multiply and shifts. Requires that the divisor not be 0, 1, +/// or -1. +static ms magic32(int32_t d) { + int32_t p; + uint32_t ad, anc, delta, q1, r1, q2, r2, t; + const uint32_t two31 = 0x80000000U; + struct ms mag; + + ad = abs(d); + t = two31 + ((uint32_t)d >> 31); + anc = t - 1 - t%ad; // absolute value of nc + p = 31; // initialize p + q1 = two31/anc; // initialize q1 = 2p/abs(nc) + r1 = two31 - q1*anc; // initialize r1 = rem(2p,abs(nc)) + q2 = two31/ad; // initialize q2 = 2p/abs(d) + r2 = two31 - q2*ad; // initialize r2 = rem(2p,abs(d)) + do { + p = p + 1; + q1 = 2*q1; // update q1 = 2p/abs(nc) + r1 = 2*r1; // update r1 = rem(2p/abs(nc)) + if (r1 >= anc) { // must be unsigned comparison + q1 = q1 + 1; + r1 = r1 - anc; + } + q2 = 2*q2; // update q2 = 2p/abs(d) + r2 = 2*r2; // update r2 = rem(2p/abs(d)) + if (r2 >= ad) { // must be unsigned comparison + q2 = q2 + 1; + r2 = r2 - ad; + } + delta = ad - r2; + } while (q1 < delta || (q1 == delta && r1 == 0)); + + mag.m = (int32_t)(q2 + 1); // make sure to sign extend + if (d < 0) mag.m = -mag.m; // resulting magic number + mag.s = p - 32; // resulting shift + return mag; +} + +/// magicu - calculate the magic numbers required to codegen an integer udiv as +/// a sequence of multiply, add and shifts. Requires that the divisor not be 0. +static mu magicu32(uint32_t d) { + int32_t p; + uint32_t nc, delta, q1, r1, q2, r2; + struct mu magu; + magu.a = 0; // initialize "add" indicator + nc = - 1 - (-d)%d; + p = 31; // initialize p + q1 = 0x80000000/nc; // initialize q1 = 2p/nc + r1 = 0x80000000 - q1*nc; // initialize r1 = rem(2p,nc) + q2 = 0x7FFFFFFF/d; // initialize q2 = (2p-1)/d + r2 = 0x7FFFFFFF - q2*d; // initialize r2 = rem((2p-1),d) + do { + p = p + 1; + if (r1 >= nc - r1 ) { + q1 = 2*q1 + 1; // update q1 + r1 = 2*r1 - nc; // update r1 + } + else { + q1 = 2*q1; // update q1 + r1 = 2*r1; // update r1 + } + if (r2 + 1 >= d - r2) { + if (q2 >= 0x7FFFFFFF) magu.a = 1; + q2 = 2*q2 + 1; // update q2 + r2 = 2*r2 + 1 - d; // update r2 + } + else { + if (q2 >= 0x80000000) magu.a = 1; + q2 = 2*q2; // update q2 + r2 = 2*r2 + 1; // update r2 + } + delta = d - 1 - r2; + } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0))); + magu.m = q2 + 1; // resulting magic number + magu.s = p - 32; // resulting shift + return magu; +} + +/// magic - calculate the magic numbers required to codegen an integer sdiv as +/// a sequence of multiply and shifts. Requires that the divisor not be 0, 1, +/// or -1. +static ms magic64(int64_t d) { + int64_t p; + uint64_t ad, anc, delta, q1, r1, q2, r2, t; + const uint64_t two63 = 9223372036854775808ULL; // 2^63 + struct ms mag; + + ad = d >= 0 ? d : -d; + t = two63 + ((uint64_t)d >> 63); + anc = t - 1 - t%ad; // absolute value of nc + p = 63; // initialize p + q1 = two63/anc; // initialize q1 = 2p/abs(nc) + r1 = two63 - q1*anc; // initialize r1 = rem(2p,abs(nc)) + q2 = two63/ad; // initialize q2 = 2p/abs(d) + r2 = two63 - q2*ad; // initialize r2 = rem(2p,abs(d)) + do { + p = p + 1; + q1 = 2*q1; // update q1 = 2p/abs(nc) + r1 = 2*r1; // update r1 = rem(2p/abs(nc)) + if (r1 >= anc) { // must be unsigned comparison + q1 = q1 + 1; + r1 = r1 - anc; + } + q2 = 2*q2; // update q2 = 2p/abs(d) + r2 = 2*r2; // update r2 = rem(2p/abs(d)) + if (r2 >= ad) { // must be unsigned comparison + q2 = q2 + 1; + r2 = r2 - ad; + } + delta = ad - r2; + } while (q1 < delta || (q1 == delta && r1 == 0)); + + mag.m = q2 + 1; + if (d < 0) mag.m = -mag.m; // resulting magic number + mag.s = p - 64; // resulting shift + return mag; +} + +/// magicu - calculate the magic numbers required to codegen an integer udiv as +/// a sequence of multiply, add and shifts. Requires that the divisor not be 0. +static mu magicu64(uint64_t d) +{ + int64_t p; + uint64_t nc, delta, q1, r1, q2, r2; + struct mu magu; + magu.a = 0; // initialize "add" indicator + nc = - 1 - (-d)%d; + p = 63; // initialize p + q1 = 0x8000000000000000ull/nc; // initialize q1 = 2p/nc + r1 = 0x8000000000000000ull - q1*nc; // initialize r1 = rem(2p,nc) + q2 = 0x7FFFFFFFFFFFFFFFull/d; // initialize q2 = (2p-1)/d + r2 = 0x7FFFFFFFFFFFFFFFull - q2*d; // initialize r2 = rem((2p-1),d) + do { + p = p + 1; + if (r1 >= nc - r1 ) { + q1 = 2*q1 + 1; // update q1 + r1 = 2*r1 - nc; // update r1 + } + else { + q1 = 2*q1; // update q1 + r1 = 2*r1; // update r1 + } + if (r2 + 1 >= d - r2) { + if (q2 >= 0x7FFFFFFFFFFFFFFFull) magu.a = 1; + q2 = 2*q2 + 1; // update q2 + r2 = 2*r2 + 1 - d; // update r2 + } + else { + if (q2 >= 0x8000000000000000ull) magu.a = 1; + q2 = 2*q2; // update q2 + r2 = 2*r2 + 1; // update r2 + } + delta = d - 1 - r2; + } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0))); + magu.m = q2 + 1; // resulting magic number + magu.s = p - 64; // resulting shift + return magu; +} + /// MaskedValueIsZero - Return true if 'Op & Mask' is known to be zero. We use /// this predicate to simplify operations downstream. Op and Mask are known to /// be the same type. @@ -209,7 +384,7 @@ return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits. case ISD::ZERO_EXTEND: SrcBits = MVT::getSizeInBits(Op.getOperand(0).getValueType()); - return MaskedValueIsZero(Op.getOperand(0),Mask & ((1ULL << SrcBits)-1),TLI); + return MaskedValueIsZero(Op.getOperand(0),Mask & (~0ULL >> (64-SrcBits)),TLI); case ISD::AssertZext: SrcBits = MVT::getSizeInBits(cast(Op.getOperand(1))->getVT()); return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits. @@ -339,7 +514,9 @@ AfterLegalize = RunningAfterLegalize; // Add all the dag nodes to the worklist. - WorkList.insert(WorkList.end(), DAG.allnodes_begin(), DAG.allnodes_end()); + for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(), + E = DAG.allnodes_end(); I != E; ++I) + WorkList.push_back(I); // Create a dummy node (which is not added to allnodes), that adds a reference // to the root node, preventing it from being deleted, and tracking any @@ -560,8 +737,7 @@ // fold (mul c1, c2) -> c1*c2 if (N0C && N1C) - return DAG.getConstant(N0C->getValue() * N1C->getValue(), - N->getValueType(0)); + return DAG.getConstant(N0C->getValue() * N1C->getValue(), VT); // canonicalize constant to RHS if (N0C && !N1C) return DAG.getNode(ISD::MUL, VT, N1, N0); @@ -570,13 +746,23 @@ return N1; // fold (mul x, -1) -> 0-x if (N1C && N1C->isAllOnesValue()) - return DAG.getNode(ISD::SUB, N->getValueType(0), - DAG.getConstant(0, N->getValueType(0)), N0); + return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT), N0); // fold (mul x, (1 << c)) -> x << c if (N1C && isPowerOf2_64(N1C->getValue())) - return DAG.getNode(ISD::SHL, N->getValueType(0), N0, + return DAG.getNode(ISD::SHL, VT, N0, DAG.getConstant(Log2_64(N1C->getValue()), TLI.getShiftAmountTy())); + // fold (mul x, -(1 << c)) -> -(x << c) or (-x) << c + if (N1C && isPowerOf2_64(-N1C->getSignExtended())) { + // FIXME: If the input is something that is easily negated (e.g. a + // single-use add), we should put the negate there. + return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT), + DAG.getNode(ISD::SHL, VT, N0, + DAG.getConstant(Log2_64(-N1C->getSignExtended()), + TLI.getShiftAmountTy()))); + } + + // fold (mul (mul x, c1), c2) -> (mul x, c1*c2) if (N1C && N0.getOpcode() == ISD::MUL) { ConstantSDNode *N00C = dyn_cast(N0.getOperand(0)); @@ -602,18 +788,58 @@ if (N0C && N1C && !N1C->isNullValue()) return DAG.getConstant(N0C->getSignExtended() / N1C->getSignExtended(), N->getValueType(0)); + // fold (sdiv X, 1) -> X + if (N1C && N1C->getSignExtended() == 1LL) + return N0; + // fold (sdiv X, -1) -> 0-X + if (N1C && N1C->isAllOnesValue()) + return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT), N0); // If we know the sign bits of both operands are zero, strength reduce to a // udiv instead. Handles (X&15) /s 4 -> X&15 >> 2 uint64_t SignBit = 1ULL << (MVT::getSizeInBits(VT)-1); if (MaskedValueIsZero(N1, SignBit, TLI) && MaskedValueIsZero(N0, SignBit, TLI)) return DAG.getNode(ISD::UDIV, N1.getValueType(), N0, N1); + // fold (sdiv X, pow2) -> (add (sra X, log(pow2)), (srl X, sizeof(X)-1)) + if (N1C && N1C->getValue() && !TLI.isIntDivCheap() && + (isPowerOf2_64(N1C->getSignExtended()) || + isPowerOf2_64(-N1C->getSignExtended()))) { + // If dividing by powers of two is cheap, then don't perform the following + // fold. + if (TLI.isPow2DivCheap()) + return SDOperand(); + int64_t pow2 = N1C->getSignExtended(); + int64_t abs2 = pow2 > 0 ? pow2 : -pow2; + SDOperand SRL = DAG.getNode(ISD::SRL, VT, N0, + DAG.getConstant(MVT::getSizeInBits(VT)-1, + TLI.getShiftAmountTy())); + WorkList.push_back(SRL.Val); + SDOperand SGN = DAG.getNode(ISD::ADD, VT, N0, SRL); + WorkList.push_back(SGN.Val); + SDOperand SRA = DAG.getNode(ISD::SRA, VT, SGN, + DAG.getConstant(Log2_64(abs2), + TLI.getShiftAmountTy())); + // If we're dividing by a positive value, we're done. Otherwise, we must + // negate the result. + if (pow2 > 0) + return SRA; + WorkList.push_back(SRA.Val); + return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT), SRA); + } + // if integer divide is expensive and we satisfy the requirements, emit an + // alternate sequence. + if (N1C && (N1C->getSignExtended() < -1 || N1C->getSignExtended() > 1) && + !TLI.isIntDivCheap()) { + SDOperand Op = BuildSDIV(N); + if (Op.Val) return Op; + } return SDOperand(); } SDOperand DAGCombiner::visitUDIV(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); + MVT::ValueType VT = N->getValueType(0); ConstantSDNode *N0C = dyn_cast(N0.Val); ConstantSDNode *N1C = dyn_cast(N1.Val); @@ -626,6 +852,12 @@ return DAG.getNode(ISD::SRL, N->getValueType(0), N0, DAG.getConstant(Log2_64(N1C->getValue()), TLI.getShiftAmountTy())); + // fold (udiv x, c) -> alternate + if (N1C && N1C->getValue() && !TLI.isIntDivCheap()) { + SDOperand Op = BuildUDIV(N); + if (Op.Val) return Op; + } + return SDOperand(); } @@ -733,14 +965,14 @@ DAG.getConstant(N1C->getValue()&N01C->getValue(), VT)); } // fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1) - if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG) { + if (N1C && N0.getOpcode() == ISD::SIGN_EXTEND_INREG) { unsigned ExtendBits = - MVT::getSizeInBits(cast(N0.getOperand(1))->getVT()); - if ((N1C->getValue() & (~0ULL << ExtendBits)) == 0) + MVT::getSizeInBits(cast(N0.getOperand(1))->getVT()); + if (ExtendBits == 64 || ((N1C->getValue() & (~0ULL << ExtendBits)) == 0)) return DAG.getNode(ISD::AND, VT, N0.getOperand(0), N1); } // fold (and (or x, 0xFFFF), 0xFF) -> 0xFF - if (N0.getOpcode() == ISD::OR && N1C) + if (N1C && N0.getOpcode() == ISD::OR) if (ConstantSDNode *ORI = dyn_cast(N0.getOperand(1))) if ((ORI->getValue() & N1C->getValue()) == N1C->getValue()) return N1; @@ -801,7 +1033,7 @@ return DAG.getNode(N0.getOpcode(), VT, ANDNode, N0.getOperand(1)); } // fold (and (sra)) -> (and (srl)) when possible. - if (N0.getOpcode() == ISD::SRA && N0.Val->hasOneUse()) + if (N0.getOpcode() == ISD::SRA && N0.Val->hasOneUse()) { if (ConstantSDNode *N01C = dyn_cast(N0.getOperand(1))) { // If the RHS of the AND has zeros where the sign bits of the SRA will // land, turn the SRA into an SRL. @@ -813,7 +1045,7 @@ return SDOperand(); } } - + } // fold (zext_inreg (extload x)) -> (zextload x) if (N0.getOpcode() == ISD::EXTLOAD) { MVT::ValueType EVT = cast(N0.getOperand(3))->getVT(); @@ -883,7 +1115,16 @@ if (N01C) return DAG.getNode(ISD::OR, VT, N0.getOperand(0), DAG.getConstant(N1C->getValue()|N01C->getValue(), VT)); + } else if (N1C && N0.getOpcode() == ISD::AND && N0.Val->hasOneUse() && + isa(N0.getOperand(1))) { + // Canonicalize (or (and X, c1), c2) -> (and (or X, c2), c1|c2) + ConstantSDNode *C1 = cast(N0.getOperand(1)); + return DAG.getNode(ISD::AND, VT, DAG.getNode(ISD::OR, VT, N0.getOperand(0), + N1), + DAG.getConstant(N1C->getValue() | C1->getValue(), VT)); } + + // fold (or (setcc x), (setcc y)) -> (setcc (or x, y)) if (isSetCCEquivalent(N0, LL, LR, CC0) && isSetCCEquivalent(N1, RL, RR, CC1)){ ISD::CondCode Op0 = cast(CC0)->get(); @@ -1747,7 +1988,10 @@ // If this is a store that kills a previous store, remove the previous store. if (Chain.getOpcode() == ISD::STORE && Chain.getOperand(2) == Ptr && - Chain.Val->hasOneUse() /* Avoid introducing DAG cycles */) { + Chain.Val->hasOneUse() /* Avoid introducing DAG cycles */ && + // Make sure that these stores are the same value type: + // FIXME: we really care that the second store is >= size of the first. + Value.getValueType() == Chain.getOperand(1).getValueType()) { // Create a new store of Value that replaces both stores. SDNode *PrevStore = Chain.Val; if (PrevStore->getOperand(1) == Value) // Same value multiply stored. @@ -2152,6 +2396,9 @@ // Canonicalize setgt X, Min --> setne X, Min if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C1 == MinVal) return DAG.getSetCC(VT, N0, N1, ISD::SETNE); + // Canonicalize setlt X, Max --> setne X, Max + if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C1 == MaxVal) + return DAG.getSetCC(VT, N0, N1, ISD::SETNE); // If we have setult X, 1, turn it into seteq X, 0 if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C1 == MinVal+1) @@ -2249,7 +2496,7 @@ if (N0.getOperand(0) == N1.getOperand(1)) return DAG.getSetCC(VT, N0.getOperand(1), N1.getOperand(0), Cond); if (N0.getOperand(1) == N1.getOperand(0)) - return DAG.getSetCC(VT, N0.getOperand(1), N1.getOperand(1), Cond); + return DAG.getSetCC(VT, N0.getOperand(0), N1.getOperand(1), Cond); } } @@ -2356,6 +2603,86 @@ return SDOperand(); } +/// BuildSDIVSequence - Given an ISD::SDIV node expressing a divide by constant, +/// return a DAG expression to select that will generate the same value by +/// multiplying by a magic number. See: +/// +SDOperand DAGCombiner::BuildSDIV(SDNode *N) { + MVT::ValueType VT = N->getValueType(0); + + // Check to see if we can do this. + if (!TLI.isTypeLegal(VT) || (VT != MVT::i32 && VT != MVT::i64)) + return SDOperand(); // BuildSDIV only operates on i32 or i64 + if (!TLI.isOperationLegal(ISD::MULHS, VT)) + return SDOperand(); // Make sure the target supports MULHS. + + int64_t d = cast(N->getOperand(1))->getSignExtended(); + ms magics = (VT == MVT::i32) ? magic32(d) : magic64(d); + + // Multiply the numerator (operand 0) by the magic value + SDOperand Q = DAG.getNode(ISD::MULHS, VT, N->getOperand(0), + DAG.getConstant(magics.m, VT)); + // If d > 0 and m < 0, add the numerator + if (d > 0 && magics.m < 0) { + Q = DAG.getNode(ISD::ADD, VT, Q, N->getOperand(0)); + WorkList.push_back(Q.Val); + } + // If d < 0 and m > 0, subtract the numerator. + if (d < 0 && magics.m > 0) { + Q = DAG.getNode(ISD::SUB, VT, Q, N->getOperand(0)); + WorkList.push_back(Q.Val); + } + // Shift right algebraic if shift value is nonzero + if (magics.s > 0) { + Q = DAG.getNode(ISD::SRA, VT, Q, + DAG.getConstant(magics.s, TLI.getShiftAmountTy())); + WorkList.push_back(Q.Val); + } + // Extract the sign bit and add it to the quotient + SDOperand T = + DAG.getNode(ISD::SRL, VT, Q, DAG.getConstant(MVT::getSizeInBits(VT)-1, + TLI.getShiftAmountTy())); + WorkList.push_back(T.Val); + return DAG.getNode(ISD::ADD, VT, Q, T); +} + +/// BuildUDIVSequence - Given an ISD::UDIV node expressing a divide by constant, +/// return a DAG expression to select that will generate the same value by +/// multiplying by a magic number. See: +/// +SDOperand DAGCombiner::BuildUDIV(SDNode *N) { + MVT::ValueType VT = N->getValueType(0); + + // Check to see if we can do this. + if (!TLI.isTypeLegal(VT) || (VT != MVT::i32 && VT != MVT::i64)) + return SDOperand(); // BuildUDIV only operates on i32 or i64 + if (!TLI.isOperationLegal(ISD::MULHU, VT)) + return SDOperand(); // Make sure the target supports MULHU. + + uint64_t d = cast(N->getOperand(1))->getValue(); + mu magics = (VT == MVT::i32) ? magicu32(d) : magicu64(d); + + // Multiply the numerator (operand 0) by the magic value + SDOperand Q = DAG.getNode(ISD::MULHU, VT, N->getOperand(0), + DAG.getConstant(magics.m, VT)); + WorkList.push_back(Q.Val); + + if (magics.a == 0) { + return DAG.getNode(ISD::SRL, VT, Q, + DAG.getConstant(magics.s, TLI.getShiftAmountTy())); + } else { + SDOperand NPQ = DAG.getNode(ISD::SUB, VT, N->getOperand(0), Q); + WorkList.push_back(NPQ.Val); + NPQ = DAG.getNode(ISD::SRL, VT, NPQ, + DAG.getConstant(1, TLI.getShiftAmountTy())); + WorkList.push_back(NPQ.Val); + NPQ = DAG.getNode(ISD::ADD, VT, NPQ, Q); + WorkList.push_back(NPQ.Val); + return DAG.getNode(ISD::SRL, VT, NPQ, + DAG.getConstant(magics.s-1, TLI.getShiftAmountTy())); + } +} + // SelectionDAG::Combine - This is the entry point for the file. // void SelectionDAG::Combine(bool RunningAfterLegalize) { Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.201 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.201.2.1 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.201 Mon Oct 17 19:27:41 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Nov 16 12:32:15 2005 @@ -394,7 +394,6 @@ // Now that we have N in, add anything that uses it if all of their operands // are now done. - for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end(); UI != E;++UI) ComputeTopDownOrdering(*UI, Order, Visited); } @@ -414,13 +413,15 @@ // entry node) that have no operands. for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(), E = DAG.allnodes_end(); I != E; ++I) { - if ((*I)->getNumOperands() == 0) { - Visited[*I] = 0 - 1U; - ComputeTopDownOrdering(*I, Order, Visited); + if (I->getNumOperands() == 0) { + Visited[I] = 0 - 1U; + ComputeTopDownOrdering(I, Order, Visited); } } - assert(Order.size() == Visited.size() && Order.size() == DAG.allnodes_size()&& + assert(Order.size() == Visited.size() && + Order.size() == + (unsigned)std::distance(DAG.allnodes_begin(), DAG.allnodes_end()) && "Error: DAG is cyclic!"); Visited.clear(); @@ -632,19 +633,26 @@ } break; } - case ISD::TokenFactor: { - std::vector Ops; - bool Changed = false; - // Legalize the operands - for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { - SDOperand Op = Node->getOperand(i); - Ops.push_back(LegalizeOp(Op)); - Changed |= Ops[i] != Op; + case ISD::TokenFactor: + if (Node->getNumOperands() == 2) { + bool Changed = false; + SDOperand Op0 = LegalizeOp(Node->getOperand(0)); + SDOperand Op1 = LegalizeOp(Node->getOperand(1)); + if (Op0 != Node->getOperand(0) || Op1 != Node->getOperand(1)) + Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Op0, Op1); + } else { + std::vector Ops; + bool Changed = false; + // Legalize the operands. + for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { + SDOperand Op = Node->getOperand(i); + Ops.push_back(LegalizeOp(Op)); + Changed |= Ops[i] != Op; + } + if (Changed) + Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Ops); } - if (Changed) - Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Ops); break; - } case ISD::CALLSEQ_START: case ISD::CALLSEQ_END: @@ -955,14 +963,37 @@ } assert(0 && "Unreachable"); } - case ISD::EXTRACT_ELEMENT: - // Get both the low and high parts. - ExpandOp(Node->getOperand(0), Tmp1, Tmp2); - if (cast(Node->getOperand(1))->getValue()) - Result = Tmp2; // 1 -> Hi - else - Result = Tmp1; // 0 -> Lo + case ISD::EXTRACT_ELEMENT: { + MVT::ValueType OpTy = Node->getOperand(0).getValueType(); + switch (getTypeAction(OpTy)) { + default: + assert(0 && "EXTRACT_ELEMENT action for type unimplemented!"); + break; + case Legal: + if (cast(Node->getOperand(1))->getValue()) { + // 1 -> Hi + Result = DAG.getNode(ISD::SRL, OpTy, Node->getOperand(0), + DAG.getConstant(MVT::getSizeInBits(OpTy)/2, + TLI.getShiftAmountTy())); + Result = DAG.getNode(ISD::TRUNCATE, Node->getValueType(0), Result); + } else { + // 0 -> Lo + Result = DAG.getNode(ISD::TRUNCATE, Node->getValueType(0), + Node->getOperand(0)); + } + Result = LegalizeOp(Result); + break; + case Expand: + // Get both the low and high parts. + ExpandOp(Node->getOperand(0), Tmp1, Tmp2); + if (cast(Node->getOperand(1))->getValue()) + Result = Tmp2; // 1 -> Hi + else + Result = Tmp1; // 0 -> Lo + break; + } break; + } case ISD::CopyToReg: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. @@ -1091,6 +1122,11 @@ if (Tmp1 != Node->getOperand(0)) Result = DAG.getNode(ISD::PCMARKER, MVT::Other, Tmp1,Node->getOperand(1)); break; + case ISD::READCYCLECOUNTER: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain + if (Tmp1 != Node->getOperand(0)) + Result = DAG.getNode(ISD::READCYCLECOUNTER, MVT::i64, Tmp1); + break; case ISD::TRUNCSTORE: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. Tmp3 = LegalizeOp(Node->getOperand(2)); // Legalize the pointer. @@ -2243,7 +2279,8 @@ // legal, such as PowerPC. if (Node->getOpcode() == ISD::FP_TO_UINT && !TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) && - TLI.isOperationLegal(ISD::FP_TO_SINT, NVT)) { + (TLI.isOperationLegal(ISD::FP_TO_SINT, NVT) || + TLI.getOperationAction(ISD::FP_TO_SINT, NVT)==TargetLowering::Custom)){ Result = DAG.getNode(ISD::FP_TO_SINT, NVT, Tmp1); } else { Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1); Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.37 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.37.2.1 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.37 Thu Oct 13 11:44:00 2005 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Wed Nov 16 12:32:15 2005 @@ -2,7 +2,7 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by Chris Lattner and is distributed under the +// This file was developed by James M. Laskey and is distributed under the // University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// @@ -21,6 +21,7 @@ #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetInstrItineraries.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -32,6 +33,7 @@ enum ScheduleChoices { noScheduling, simpleScheduling, + simpleNoItinScheduling }; } // namespace @@ -43,6 +45,8 @@ "Trivial emission with no analysis"), clEnumValN(simpleScheduling, "simple", "Minimize critical path and maximize processor utilization"), + clEnumValN(simpleNoItinScheduling, "simple-noitin", + "Same as simple except using generic latency"), clEnumValEnd)); @@ -97,65 +101,74 @@ typedef typename std::vector::iterator Iter; // Tally iterator - /// AllInUse - Test to see if all of the resources in the slot are busy (set.) - inline bool AllInUse(Iter Cursor, unsigned ResourceSet) { - return (*Cursor & ResourceSet) == ResourceSet; - } - - /// Skip - Skip over slots that use all of the specified resource (all are - /// set.) - Iter Skip(Iter Cursor, unsigned ResourceSet) { - assert(ResourceSet && "At least one resource bit needs to bet set"); - - // Continue to the end - while (true) { - // Break out if one of the resource bits is not set - if (!AllInUse(Cursor, ResourceSet)) return Cursor; - // Try next slot - Cursor++; - assert(Cursor < Tally.end() && "Tally is not large enough for schedule"); - } - } - - /// FindSlots - Starting from Begin, locate N consecutive slots where at least - /// one of the resource bits is available. Returns the address of first slot. - Iter FindSlots(Iter Begin, unsigned N, unsigned ResourceSet, - unsigned &Resource) { - // Track position - Iter Cursor = Begin; + /// SlotsAvailable - Returns true if all units are available. + /// + bool SlotsAvailable(Iter Begin, unsigned N, unsigned ResourceSet, + unsigned &Resource) { + assert(N && "Must check availability with N != 0"); + // Determine end of interval + Iter End = Begin + N; + assert(End <= Tally.end() && "Tally is not large enough for schedule"); - // Try all possible slots forward - while (true) { - // Skip full slots - Cursor = Skip(Cursor, ResourceSet); - // Determine end of interval - Iter End = Cursor + N; - assert(End <= Tally.end() && "Tally is not large enough for schedule"); + // Iterate thru each resource + BitsIterator Resources(ResourceSet & ~*Begin); + while (unsigned Res = Resources.Next()) { + // Check if resource is available for next N slots + Iter Interval = End; + do { + Interval--; + if (*Interval & Res) break; + } while (Interval != Begin); - // Iterate thru each resource - BitsIterator Resources(ResourceSet & ~*Cursor); - while (unsigned Res = Resources.Next()) { - // Check if resource is available for next N slots - // Break out if resource is busy - Iter Interval = Cursor; - for (; Interval < End && !(*Interval & Res); Interval++) {} - - // If available for interval, return where and which resource - if (Interval == End) { - Resource = Res; - return Cursor; - } - // Otherwise, check if worth checking other resources - if (AllInUse(Interval, ResourceSet)) { - // Start looking beyond interval - Cursor = Interval; - break; - } + // If available for N + if (Interval == Begin) { + // Success + Resource = Res; + return true; } - Cursor++; } + + // No luck + Resource = 0; + return false; + } + + /// RetrySlot - Finds a good candidate slot to retry search. + Iter RetrySlot(Iter Begin, unsigned N, unsigned ResourceSet) { + assert(N && "Must check availability with N != 0"); + // Determine end of interval + Iter End = Begin + N; + assert(End <= Tally.end() && "Tally is not large enough for schedule"); + + while (Begin != End--) { + // Clear units in use + ResourceSet &= ~*End; + // If no units left then we should go no further + if (!ResourceSet) return End + 1; + } + // Made it all the way through + return Begin; + } + + /// FindAndReserveStages - Return true if the stages can be completed. If + /// so mark as busy. + bool FindAndReserveStages(Iter Begin, + InstrStage *Stage, InstrStage *StageEnd) { + // If at last stage then we're done + if (Stage == StageEnd) return true; + // Get number of cycles for current stage + unsigned N = Stage->Cycles; + // Check to see if N slots are available, if not fail + unsigned Resource; + if (!SlotsAvailable(Begin, N, Stage->Units, Resource)) return false; + // Check to see if remaining stages are available, if not fail + if (!FindAndReserveStages(Begin + N, Stage + 1, StageEnd)) return false; + // Reserve resource + Reserve(Begin, N, Resource); + // Success + return true; } - + /// Reserve - Mark busy (set) the specified N slots. void Reserve(Iter Begin, unsigned N, unsigned Resource) { // Determine end of interval @@ -167,24 +180,39 @@ *Begin |= Resource; } + /// FindSlots - Starting from Begin, locate consecutive slots where all stages + /// can be completed. Returns the address of first slot. + Iter FindSlots(Iter Begin, InstrStage *StageBegin, InstrStage *StageEnd) { + // Track position + Iter Cursor = Begin; + + // Try all possible slots forward + while (true) { + // Try at cursor, if successful return position. + if (FindAndReserveStages(Cursor, StageBegin, StageEnd)) return Cursor; + // Locate a better position + Cursor = RetrySlot(Cursor + 1, StageBegin->Cycles, StageBegin->Units); + } + } + public: /// Initialize - Resize and zero the tally to the specified number of time /// slots. inline void Initialize(unsigned N) { Tally.assign(N, 0); // Initialize tally to all zeros. } - - // FindAndReserve - Locate and mark busy (set) N bits started at slot I, using - // ResourceSet for choices. - unsigned FindAndReserve(unsigned I, unsigned N, unsigned ResourceSet) { - // Which resource used - unsigned Resource; - // Find slots for instruction. - Iter Where = FindSlots(Tally.begin() + I, N, ResourceSet, Resource); - // Reserve the slots - Reserve(Where, N, Resource); - // Return time slot (index) - return Where - Tally.begin(); + + // FindAndReserve - Locate an ideal slot for the specified stages and mark + // as busy. + unsigned FindAndReserve(unsigned Slot, InstrStage *StageBegin, + InstrStage *StageEnd) { + // Where to begin + Iter Begin = Tally.begin() + Slot; + // Find a free slot + Iter Where = FindSlots(Begin, StageBegin, StageEnd); + // Distance is slot number + unsigned Final = Where - Tally.begin(); + return Final; } }; @@ -192,27 +220,46 @@ // Forward class NodeInfo; -typedef std::vector NIVector; -typedef std::vector::iterator NIIterator; +typedef NodeInfo *NodeInfoPtr; +typedef std::vector NIVector; +typedef std::vector::iterator NIIterator; //===----------------------------------------------------------------------===// /// /// Node group - This struct is used to manage flagged node groups. /// -class NodeGroup : public NIVector { +class NodeGroup { private: + NIVector Members; // Group member nodes + NodeInfo *Dominator; // Node with highest latency + unsigned Latency; // Total latency of the group int Pending; // Number of visits pending before // adding to order public: // Ctor. - NodeGroup() : Pending(0) {} + NodeGroup() : Dominator(NULL), Pending(0) {} // Accessors - inline NodeInfo *getLeader() { return empty() ? NULL : front(); } + inline void setDominator(NodeInfo *D) { Dominator = D; } + inline NodeInfo *getDominator() { return Dominator; } + inline void setLatency(unsigned L) { Latency = L; } + inline unsigned getLatency() { return Latency; } inline int getPending() const { return Pending; } inline void setPending(int P) { Pending = P; } inline int addPending(int I) { return Pending += I; } + + // Pass thru + inline bool group_empty() { return Members.empty(); } + inline NIIterator group_begin() { return Members.begin(); } + inline NIIterator group_end() { return Members.end(); } + inline void group_push_back(const NodeInfoPtr &NI) { Members.push_back(NI); } + inline NIIterator group_insert(NIIterator Pos, const NodeInfoPtr &NI) { + return Members.insert(Pos, NI); + } + inline void group_insert(NIIterator Pos, NIIterator First, NIIterator Last) { + Members.insert(Pos, First, Last); + } static void Add(NodeInfo *D, NodeInfo *U); static unsigned CountInternalUses(NodeInfo *D, NodeInfo *U); @@ -230,8 +277,9 @@ // adding to order public: SDNode *Node; // DAG node - unsigned Latency; // Cycles to complete instruction - unsigned ResourceSet; // Bit vector of usable resources + InstrStage *StageBegin; // First stage in itinerary + InstrStage *StageEnd; // Last+1 stage in itinerary + unsigned Latency; // Total cycles to complete instruction bool IsCall; // Is function call unsigned Slot; // Node's time slot NodeGroup *Group; // Grouping information @@ -244,8 +292,9 @@ NodeInfo(SDNode *N = NULL) : Pending(0) , Node(N) + , StageBegin(NULL) + , StageEnd(NULL) , Latency(0) - , ResourceSet(0) , IsCall(false) , Slot(0) , Group(NULL) @@ -257,11 +306,11 @@ // Accessors inline bool isInGroup() const { - assert(!Group || !Group->empty() && "Group with no members"); + assert(!Group || !Group->group_empty() && "Group with no members"); return Group != NULL; } - inline bool isGroupLeader() const { - return isInGroup() && Group->getLeader() == this; + inline bool isGroupDominator() const { + return isInGroup() && Group->getDominator() == this; } inline int getPending() const { return Group ? Group->getPending() : Pending; @@ -298,8 +347,8 @@ if (N->isInGroup()) { // get Group NodeGroup *Group = NI->Group; - NGI = Group->begin(); - NGE = Group->end(); + NGI = Group->group_begin(); + NGE = Group->group_end(); // Prevent this node from being used (will be in members list NI = NULL; } @@ -353,7 +402,8 @@ public: // Ctor. - NodeGroupOpIterator(NodeInfo *N) : NI(N), GI(N) {} + NodeGroupOpIterator(NodeInfo *N) + : NI(N), GI(N), OI(SDNode::op_iterator()), OE(SDNode::op_iterator()) {} /// isEnd - Returns true when not more operands are available. /// @@ -375,15 +425,6 @@ /// class SimpleSched { private: - // TODO - get ResourceSet from TII - enum { - RSInteger = 0x3, // Two integer units - RSFloat = 0xC, // Two float units - RSLoadStore = 0x30, // Two load store units - RSBranch = 0x400, // One branch unit - RSOther = 0 // Processing unit independent - }; - MachineBasicBlock *BB; // Current basic block SelectionDAG &DAG; // DAG of the current basic block const TargetMachine &TM; // Target processor @@ -392,6 +433,7 @@ SSARegMap *RegMap; // Virtual/real register map MachineConstantPool *ConstPool; // Target constant pool unsigned NodeCount; // Number of nodes in DAG + bool HasGroups; // True if there are any groups NodeInfo *Info; // Info for nodes being scheduled std::map Map; // Map nodes to info NIVector Ordering; // Emit ordering of nodes @@ -406,7 +448,7 @@ : BB(bb), DAG(D), TM(D.getTarget()), TII(*TM.getInstrInfo()), MRI(*TM.getRegisterInfo()), RegMap(BB->getParent()->getSSARegMap()), ConstPool(BB->getParent()->getConstantPool()), - NodeCount(0), Info(NULL), Map(), Tally(), NSlots(0) { + NodeCount(0), HasGroups(false), Info(NULL), Map(), Tally(), NSlots(0) { assert(&TII && "Target doesn't provide instr info?"); assert(&MRI && "Target doesn't provide register info?"); } @@ -439,6 +481,7 @@ void Schedule(); void IdentifyGroups(); void GatherSchedulingInfo(); + void FakeGroupDominators(); void PrepareNodeInfo(); bool isStrongDependency(NodeInfo *A, NodeInfo *B); bool isWeakDependency(NodeInfo *A, NodeInfo *B); @@ -458,6 +501,27 @@ inline void dump(const char *tag) const { std::cerr << tag; dump(); } void dump() const; }; + + +//===----------------------------------------------------------------------===// +/// Special case itineraries. +/// +enum { + CallLatency = 40, // To push calls back in time + + RSInteger = 0xC0000000, // Two integer units + RSFloat = 0x30000000, // Two float units + RSLoadStore = 0x0C000000, // Two load store units + RSBranch = 0x02000000 // One branch unit +}; +static InstrStage CallStage = { CallLatency, RSBranch }; +static InstrStage LoadStage = { 5, RSLoadStore }; +static InstrStage StoreStage = { 2, RSLoadStore }; +static InstrStage IntStage = { 2, RSInteger }; +static InstrStage FloatStage = { 3, RSFloat }; +//===----------------------------------------------------------------------===// + + //===----------------------------------------------------------------------===// } // namespace @@ -491,7 +555,8 @@ } } // Merge the two lists - DGroup->insert(DGroup->end(), UGroup->begin(), UGroup->end()); + DGroup->group_insert(DGroup->group_end(), + UGroup->group_begin(), UGroup->group_end()); } else if (DGroup) { // Make user member of definers group U->Group = DGroup; @@ -503,7 +568,7 @@ // Remove internal edges DGroup->addPending(-CountInternalUses(DNI, U)); } - DGroup->push_back(U); + DGroup->group_push_back(U); } else if (UGroup) { // Make definer member of users group D->Group = UGroup; @@ -515,13 +580,13 @@ // Remove internal edges UGroup->addPending(-CountInternalUses(D, UNI)); } - UGroup->insert(UGroup->begin(), D); + UGroup->group_insert(UGroup->group_begin(), D); } else { D->Group = U->Group = DGroup = new NodeGroup(); DGroup->addPending(D->Node->use_size() + U->Node->use_size() - CountInternalUses(D, U)); - DGroup->push_back(D); - DGroup->push_back(U); + DGroup->group_push_back(D); + DGroup->group_push_back(U); } } @@ -529,10 +594,11 @@ /// unsigned NodeGroup::CountInternalUses(NodeInfo *D, NodeInfo *U) { unsigned N = 0; - for (SDNode:: use_iterator UI = D->Node->use_begin(), - E = D->Node->use_end(); UI != E; UI++) { - if (*UI == U->Node) N++; + for (unsigned M = U->Node->getNumOperands(); 0 < M--;) { + SDOperand Op = U->Node->getOperand(M); + if (Op.Val == D->Node) N++; } + return N; } //===----------------------------------------------------------------------===// @@ -587,9 +653,9 @@ /// IncludeNode - Add node to NodeInfo vector. /// void SimpleSched::IncludeNode(NodeInfo *NI) { - // Get node - SDNode *Node = NI->Node; - // Ignore entry node +// Get node +SDNode *Node = NI->Node; +// Ignore entry node if (Node->getOpcode() == ISD::EntryToken) return; // Check current count for node int Count = NI->getPending(); @@ -601,7 +667,7 @@ if (!Count) { // Add node if (NI->isInGroup()) { - Ordering.push_back(NI->Group->getLeader()); + Ordering.push_back(NI->Group->getDominator()); } else { Ordering.push_back(NI); } @@ -662,6 +728,8 @@ if (Op.getValueType() != MVT::Flag) break; // Add to node group NodeGroup::Add(getNI(Op.Val), NI); + // Let evryone else know + HasGroups = true; } } } @@ -669,8 +737,8 @@ /// GatherSchedulingInfo - Get latency and resource information about each node. /// void SimpleSched::GatherSchedulingInfo() { - // Track if groups are present - bool AreGroups = false; + // Get instruction itineraries for the target + const InstrItineraryData InstrItins = TM.getInstrItineraryData(); // For each node for (unsigned i = 0, N = NodeCount; i < N; i++) { @@ -678,90 +746,87 @@ NodeInfo* NI = &Info[i]; SDNode *Node = NI->Node; - // Test for groups - if (NI->isInGroup()) AreGroups = true; - - // FIXME: Pretend by using value type to choose metrics - MVT::ValueType VT = Node->getValueType(0); - - // If machine opcode - if (Node->isTargetOpcode()) { - MachineOpCode TOpc = Node->getTargetOpcode(); - // FIXME: This is an ugly (but temporary!) hack to test the scheduler - // before we have real target info. - // FIXME NI->Latency = std::max(1, TII.maxLatency(TOpc)); - // FIXME NI->ResourceSet = TII.resources(TOpc); - if (TII.isCall(TOpc)) { - NI->ResourceSet = RSBranch; - NI->Latency = 40; - NI->IsCall = true; - } else if (TII.isLoad(TOpc)) { - NI->ResourceSet = RSLoadStore; - NI->Latency = 5; - } else if (TII.isStore(TOpc)) { - NI->ResourceSet = RSLoadStore; - NI->Latency = 2; - } else if (MVT::isInteger(VT)) { - NI->ResourceSet = RSInteger; - NI->Latency = 2; - } else if (MVT::isFloatingPoint(VT)) { - NI->ResourceSet = RSFloat; - NI->Latency = 3; - } else { - NI->ResourceSet = RSOther; - NI->Latency = 0; - } - } else { - if (MVT::isInteger(VT)) { - NI->ResourceSet = RSInteger; - NI->Latency = 2; - } else if (MVT::isFloatingPoint(VT)) { - NI->ResourceSet = RSFloat; - NI->Latency = 3; - } else { - NI->ResourceSet = RSOther; - NI->Latency = 0; + // If there are itineraries and it is a machine instruction + if (InstrItins.isEmpty() || ScheduleStyle == simpleNoItinScheduling) { + // If machine opcode + if (Node->isTargetOpcode()) { + // Get return type to guess which processing unit + MVT::ValueType VT = Node->getValueType(0); + // Get machine opcode + MachineOpCode TOpc = Node->getTargetOpcode(); + NI->IsCall = TII.isCall(TOpc); + + if (TII.isLoad(TOpc)) NI->StageBegin = &LoadStage; + else if (TII.isStore(TOpc)) NI->StageBegin = &StoreStage; + else if (MVT::isInteger(VT)) NI->StageBegin = &IntStage; + else if (MVT::isFloatingPoint(VT)) NI->StageBegin = &FloatStage; + if (NI->StageBegin) NI->StageEnd = NI->StageBegin + 1; } + } else if (Node->isTargetOpcode()) { + // get machine opcode + MachineOpCode TOpc = Node->getTargetOpcode(); + // Check to see if it is a call + NI->IsCall = TII.isCall(TOpc); + // Get itinerary stages for instruction + unsigned II = TII.getSchedClass(TOpc); + NI->StageBegin = InstrItins.begin(II); + NI->StageEnd = InstrItins.end(II); + } + + // One slot for the instruction itself + NI->Latency = 1; + + // Add long latency for a call to push it back in time + if (NI->IsCall) NI->Latency += CallLatency; + + // Sum up all the latencies + for (InstrStage *Stage = NI->StageBegin, *E = NI->StageEnd; + Stage != E; Stage++) { + NI->Latency += Stage->Cycles; } - // Add one slot for the instruction itself - NI->Latency++; - // Sum up all the latencies for max tally size NSlots += NI->Latency; } // Unify metrics if in a group - if (AreGroups) { + if (HasGroups) { for (unsigned i = 0, N = NodeCount; i < N; i++) { NodeInfo* NI = &Info[i]; - if (NI->isGroupLeader()) { + if (NI->isInGroup()) { NodeGroup *Group = NI->Group; - unsigned Latency = 0; - unsigned MaxLat = 0; - unsigned ResourceSet = 0; - bool IsCall = false; - for (NIIterator NGI = Group->begin(), NGE = Group->end(); - NGI != NGE; NGI++) { - NodeInfo* NGNI = *NGI; - Latency += NGNI->Latency; - IsCall = IsCall || NGNI->IsCall; + if (!Group->getDominator()) { + NIIterator NGI = Group->group_begin(), NGE = Group->group_end(); + NodeInfo *Dominator = *NGI; + unsigned Latency = 0; - if (MaxLat < NGNI->Latency) { - MaxLat = NGNI->Latency; - ResourceSet = NGNI->ResourceSet; + for (NGI++; NGI != NGE; NGI++) { + NodeInfo* NGNI = *NGI; + Latency += NGNI->Latency; + if (Dominator->Latency < NGNI->Latency) Dominator = NGNI; } - NGNI->Latency = 0; - NGNI->ResourceSet = 0; - NGNI->IsCall = false; + Dominator->Latency = Latency; + Group->setDominator(Dominator); } - - NI->Latency = Latency; - NI->ResourceSet = ResourceSet; - NI->IsCall = IsCall; + } + } + } +} + +/// FakeGroupDominators - Set dominators for non-scheduling. +/// +void SimpleSched::FakeGroupDominators() { + for (unsigned i = 0, N = NodeCount; i < N; i++) { + NodeInfo* NI = &Info[i]; + + if (NI->isInGroup()) { + NodeGroup *Group = NI->Group; + + if (!Group->getDominator()) { + Group->setDominator(NI); } } } @@ -772,21 +837,18 @@ void SimpleSched::PrepareNodeInfo() { // Allocate node information Info = new NodeInfo[NodeCount]; - // Get base of all nodes table - SelectionDAG::allnodes_iterator AllNodes = DAG.allnodes_begin(); - - // For each node being scheduled - for (unsigned i = 0, N = NodeCount; i < N; i++) { - // Get next node from DAG all nodes table - SDNode *Node = AllNodes[i]; + + unsigned i = 0; + for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(), + E = DAG.allnodes_end(); I != E; ++I, ++i) { // Fast reference to node schedule info NodeInfo* NI = &Info[i]; // Set up map - Map[Node] = NI; + Map[I] = NI; // Set node - NI->Node = Node; + NI->Node = I; // Set pending visit count - NI->setPending(Node->use_size()); + NI->setPending(I->use_size()); } } @@ -798,7 +860,8 @@ } /// isWeakDependency Return true if node A produces a result that will -/// conflict with operands of B. +/// conflict with operands of B. It is assumed that we have called +/// isStrongDependency prior. bool SimpleSched::isWeakDependency(NodeInfo *A, NodeInfo *B) { // TODO check for conflicting real registers and aliases #if 0 // FIXME - Since we are in SSA form and not checking register aliasing @@ -843,9 +906,11 @@ // If independent of others (or first entry) if (Slot == NotFound) Slot = 0; +#if 0 // FIXME - measure later // Find a slot where the needed resources are available - if (NI->ResourceSet) - Slot = Tally.FindAndReserve(Slot, NI->Latency, NI->ResourceSet); + if (NI->StageBegin != NI->StageEnd) + Slot = Tally.FindAndReserve(Slot, NI->StageBegin, NI->StageEnd); +#endif // Set node slot NI->Slot = Slot; @@ -899,8 +964,8 @@ if (Slot == NotFound) Slot = 0; // Find a slot where the needed resources are available - if (NI->ResourceSet) - Slot = Tally.FindAndReserve(Slot, NI->Latency, NI->ResourceSet); + if (NI->StageBegin != NI->StageEnd) + Slot = Tally.FindAndReserve(Slot, NI->StageBegin, NI->StageEnd); // Set node slot NI->Slot = Slot; @@ -930,7 +995,7 @@ // Iterate through nodes NodeGroupIterator NGI(Ordering[i]); if (NI->isInGroup()) { - if (NI->isGroupLeader()) { + if (NI->isGroupDominator()) { NodeGroupIterator NGI(Ordering[i]); while (NodeInfo *NI = NGI.next()) EmitNode(NI); } @@ -1006,7 +1071,28 @@ // Add result register values for things that are defined by this // instruction. - if (NumResults) VRBase = CreateVirtualRegisters(MI, NumResults, II); + + // If the node is only used by a CopyToReg and the dest reg is a vreg, use + // the CopyToReg'd destination register instead of creating a new vreg. + if (NumResults == 1) { + for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); + UI != E; ++UI) { + SDNode *Use = *UI; + if (Use->getOpcode() == ISD::CopyToReg && + Use->getOperand(2).Val == Node) { + unsigned Reg = cast(Use->getOperand(1))->getReg(); + if (MRegisterInfo::isVirtualRegister(Reg)) { + VRBase = Reg; + MI->addRegOperand(Reg, MachineOperand::Def); + break; + } + } + } + } + + // Otherwise, create new virtual registers. + if (NumResults && VRBase == 0) + VRBase = CreateVirtualRegisters(MI, NumResults, II); // Emit all of the actual operands of this instruction, adding them to the // instruction as appropriate. @@ -1084,10 +1170,11 @@ case ISD::TokenFactor: break; case ISD::CopyToReg: { - unsigned Val = getVR(Node->getOperand(2)); - MRI.copyRegToReg(*BB, BB->end(), - cast(Node->getOperand(1))->getReg(), Val, - RegMap->getRegClass(Val)); + unsigned InReg = getVR(Node->getOperand(2)); + unsigned DestReg = cast(Node->getOperand(1))->getReg(); + if (InReg != DestReg) // Coallesced away the copy? + MRI.copyRegToReg(*BB, BB->end(), DestReg, InReg, + RegMap->getRegClass(InReg)); break; } case ISD::CopyFromReg: { @@ -1097,21 +1184,40 @@ break; } + // If the node is only used by a CopyToReg and the dest reg is a vreg, use + // the CopyToReg'd destination register instead of creating a new vreg. + for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); + UI != E; ++UI) { + SDNode *Use = *UI; + if (Use->getOpcode() == ISD::CopyToReg && + Use->getOperand(2).Val == Node) { + unsigned DestReg = cast(Use->getOperand(1))->getReg(); + if (MRegisterInfo::isVirtualRegister(DestReg)) { + VRBase = DestReg; + break; + } + } + } + // Figure out the register class to create for the destreg. const TargetRegisterClass *TRC = 0; + if (VRBase) { + TRC = RegMap->getRegClass(VRBase); + } else { - // Pick the register class of the right type that contains this physreg. - for (MRegisterInfo::regclass_iterator I = MRI.regclass_begin(), - E = MRI.regclass_end(); I != E; ++I) - if ((*I)->getType() == Node->getValueType(0) && - (*I)->contains(SrcReg)) { - TRC = *I; - break; - } - assert(TRC && "Couldn't find register class for reg copy!"); + // Pick the register class of the right type that contains this physreg. + for (MRegisterInfo::regclass_iterator I = MRI.regclass_begin(), + E = MRI.regclass_end(); I != E; ++I) + if ((*I)->getType() == Node->getValueType(0) && + (*I)->contains(SrcReg)) { + TRC = *I; + break; + } + assert(TRC && "Couldn't find register class for reg copy!"); - // Create the reg, emit the copy. - VRBase = RegMap->createVirtualRegister(TRC); + // Create the reg, emit the copy. + VRBase = RegMap->createVirtualRegister(TRC); + } MRI.copyRegToReg(*BB, BB->end(), VRBase, SrcReg, TRC); break; } @@ -1126,11 +1232,23 @@ /// void SimpleSched::Schedule() { // Number the nodes - NodeCount = DAG.allnodes_size(); - // Set up minimum info for scheduling. + NodeCount = std::distance(DAG.allnodes_begin(), DAG.allnodes_end()); + // Test to see if scheduling should occur + bool ShouldSchedule = NodeCount > 3 && ScheduleStyle != noScheduling; + // Set up minimum info for scheduling PrepareNodeInfo(); // Construct node groups for flagged nodes IdentifyGroups(); + + // Don't waste time if is only entry and return + if (ShouldSchedule) { + // Get latency and resource requirements + GatherSchedulingInfo(); + } else if (HasGroups) { + // Make sure all the groups have dominators + FakeGroupDominators(); + } + // Breadth first walk of DAG VisitAll(); @@ -1144,10 +1262,7 @@ #endif // Don't waste time if is only entry and return - if (NodeCount > 3 && ScheduleStyle != noScheduling) { - // Get latency and resource requirements - GatherSchedulingInfo(); - + if (ShouldSchedule) { // Push back long instructions and critical path ScheduleBackward(); @@ -1182,9 +1297,9 @@ std::cerr << " " << NI->Preorder << ". "; printSI(std::cerr, NI); std::cerr << "\n"; - if (NI->isGroupLeader()) { + if (NI->isGroupDominator()) { NodeGroup *Group = NI->Group; - for (NIIterator NII = Group->begin(), E = Group->end(); + for (NIIterator NII = Group->group_begin(), E = Group->group_end(); NII != E; NII++) { std::cerr << " "; printSI(std::cerr, *NII); @@ -1205,7 +1320,6 @@ SDNode *Node = NI->Node; O << " " << std::hex << Node << std::dec - << ", RS=" << NI->ResourceSet << ", Lat=" << NI->Latency << ", Slot=" << NI->Slot << ", ARITY=(" << Node->getNumOperands() << "," @@ -1226,9 +1340,9 @@ NodeInfo *NI = Ordering[i]; printSI(O, NI); O << "\n"; - if (NI->isGroupLeader()) { + if (NI->isGroupDominator()) { NodeGroup *Group = NI->Group; - for (NIIterator NII = Group->begin(), E = Group->end(); + for (NIIterator NII = Group->group_begin(), E = Group->group_end(); NII != E; NII++) { O << " "; printSI(O, *NII); Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.206 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.206.2.1 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.206 Wed Oct 12 22:11:28 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed Nov 16 12:32:15 2005 @@ -167,63 +167,63 @@ /// chain but no other uses and no side effect. If a node is passed in as an /// argument, it is used as the seed for node deletion. void SelectionDAG::RemoveDeadNodes(SDNode *N) { - std::set AllNodeSet(AllNodes.begin(), AllNodes.end()); - // Create a dummy node (which is not added to allnodes), that adds a reference // to the root node, preventing it from being deleted. HandleSDNode Dummy(getRoot()); + bool MadeChange = false; + // If we have a hint to start from, use it. - if (N) DeleteNodeIfDead(N, &AllNodeSet); - - Restart: - unsigned NumNodes = AllNodeSet.size(); - for (std::set::iterator I = AllNodeSet.begin(), E = AllNodeSet.end(); - I != E; ++I) { - // Try to delete this node. - DeleteNodeIfDead(*I, &AllNodeSet); - - // If we actually deleted any nodes, do not use invalid iterators in - // AllNodeSet. - if (AllNodeSet.size() != NumNodes) - goto Restart; - } - - // Restore AllNodes. - if (AllNodes.size() != NumNodes) - AllNodes.assign(AllNodeSet.begin(), AllNodeSet.end()); + if (N && N->use_empty()) { + DestroyDeadNode(N); + MadeChange = true; + } + for (allnodes_iterator I = allnodes_begin(), E = allnodes_end(); I != E; ++I) + if (I->use_empty() && I->getOpcode() != 65535) { + // Node is dead, recursively delete newly dead uses. + DestroyDeadNode(I); + MadeChange = true; + } + + // Walk the nodes list, removing the nodes we've marked as dead. + if (MadeChange) { + for (allnodes_iterator I = allnodes_begin(), E = allnodes_end(); I != E; ) { + SDNode *N = I++; + if (N->use_empty()) + AllNodes.erase(N); + } + } + // If the root changed (e.g. it was a dead load, update the root). setRoot(Dummy.getValue()); } - -void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) { - if (!N->use_empty()) - return; - +/// DestroyDeadNode - We know that N is dead. Nuke it from the CSE maps for the +/// graph. If it is the last user of any of its operands, recursively process +/// them the same way. +/// +void SelectionDAG::DestroyDeadNode(SDNode *N) { // Okay, we really are going to delete this node. First take this out of the // appropriate CSE map. RemoveNodeFromCSEMaps(N); // Next, brutally remove the operand list. This is safe to do, as there are // no cycles in the graph. - while (!N->Operands.empty()) { - SDNode *O = N->Operands.back().Val; - N->Operands.pop_back(); + for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) { + SDNode *O = I->Val; O->removeUser(N); // Now that we removed this operand, see if there are no uses of it left. - DeleteNodeIfDead(O, NodeSet); + if (O->use_empty()) + DestroyDeadNode(O); } - - // Remove the node from the nodes set and delete it. - std::set &AllNodeSet = *(std::set*)NodeSet; - AllNodeSet.erase(N); - - // Now that the node is gone, check to see if any of the operands of this node - // are dead now. - delete N; + delete[] N->OperandList; + N->OperandList = 0; + N->NumOperands = 0; + + // Mark the node as dead. + N->MorphNodeTo(65535); } void SelectionDAG::DeleteNode(SDNode *N) { @@ -240,22 +240,14 @@ void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) { // Remove it from the AllNodes list. - for (std::vector::iterator I = AllNodes.begin(); ; ++I) { - assert(I != AllNodes.end() && "Node not in AllNodes list??"); - if (*I == N) { - // Erase from the vector, which is not ordered. - std::swap(*I, AllNodes.back()); - AllNodes.pop_back(); - break; - } - } + AllNodes.remove(N); // Drop all of the operands and decrement used nodes use counts. - while (!N->Operands.empty()) { - SDNode *O = N->Operands.back().Val; - N->Operands.pop_back(); - O->removeUser(N); - } + for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) + I->Val->removeUser(N); + delete[] N->OperandList; + N->OperandList = 0; + N->NumOperands = 0; delete N; } @@ -312,6 +304,9 @@ case ISD::ExternalSymbol: Erased = ExternalSymbols.erase(cast(N)->getSymbol()); break; + case ISD::TargetExternalSymbol: + Erased = TargetExternalSymbols.erase(cast(N)->getSymbol()); + break; case ISD::VALUETYPE: Erased = ValueTypeNodes[cast(N)->getVT()] != 0; ValueTypeNodes[cast(N)->getVT()] = 0; @@ -419,14 +414,18 @@ AN = N; } return 0; - } SelectionDAG::~SelectionDAG() { - for (unsigned i = 0, e = AllNodes.size(); i != e; ++i) - delete AllNodes[i]; + while (!AllNodes.empty()) { + SDNode *N = AllNodes.begin(); + delete [] N->OperandList; + N->OperandList = 0; + N->NumOperands = 0; + AllNodes.pop_front(); + } } SDOperand SelectionDAG::getZeroExtendInReg(SDOperand Op, MVT::ValueType VT) { @@ -551,7 +550,15 @@ SDOperand SelectionDAG::getExternalSymbol(const char *Sym, MVT::ValueType VT) { SDNode *&N = ExternalSymbols[Sym]; if (N) return SDOperand(N, 0); - N = new ExternalSymbolSDNode(Sym, VT); + N = new ExternalSymbolSDNode(false, Sym, VT); + AllNodes.push_back(N); + return SDOperand(N, 0); +} + +SDOperand SelectionDAG::getTargetExternalSymbol(const char *Sym, MVT::ValueType VT) { + SDNode *&N = TargetExternalSymbols[Sym]; + if (N) return SDOperand(N, 0); + N = new ExternalSymbolSDNode(true, Sym, VT); AllNodes.push_back(N); return SDOperand(N, 0); } @@ -1065,9 +1072,9 @@ assert((getOpcode() == ISD::CALLSEQ_START || getOpcode() == ISD::CALLSEQ_END) && "Cannot adjust this node!"); - Operands[0].Val->removeUser(this); - Operands[0] = N; - N.Val->Uses.push_back(this); + OperandList[0].Val->removeUser(this); + OperandList[0] = N; + OperandList[0].Val->Uses.push_back(this); } @@ -1080,7 +1087,7 @@ N = new SDNode(ISD::LOAD, Chain, Ptr, SV); // Loads have a token chain. - N->setValueTypes(VT, MVT::Other); + setNodeValueTypes(N, VT, MVT::Other); AllNodes.push_back(N); return SDOperand(N, 0); } @@ -1198,7 +1205,7 @@ case 3: return getNode(Opcode, VT, Ops[0], Ops[1], Ops[2]); default: break; } - + ConstantSDNode *N1C = dyn_cast(Ops[1].Val); switch (Opcode) { default: break; @@ -1324,11 +1331,46 @@ } else { N = new SDNode(Opcode, Ops); } - N->setValueTypes(ResultTys); + setNodeValueTypes(N, ResultTys); AllNodes.push_back(N); return SDOperand(N, 0); } +void SelectionDAG::setNodeValueTypes(SDNode *N, + std::vector &RetVals) { + switch (RetVals.size()) { + case 0: return; + case 1: N->setValueTypes(RetVals[0]); return; + case 2: setNodeValueTypes(N, RetVals[0], RetVals[1]); return; + default: break; + } + + std::list >::iterator I = + std::find(VTList.begin(), VTList.end(), RetVals); + if (I == VTList.end()) { + VTList.push_front(RetVals); + I = VTList.begin(); + } + + N->setValueTypes(&(*I)[0], I->size()); +} + +void SelectionDAG::setNodeValueTypes(SDNode *N, MVT::ValueType VT1, + MVT::ValueType VT2) { + for (std::list >::iterator I = VTList.begin(), + E = VTList.end(); I != E; ++I) { + if (I->size() == 2 && (*I)[0] == VT1 && (*I)[1] == VT2) { + N->setValueTypes(&(*I)[0], 2); + return; + } + } + std::vector V; + V.push_back(VT1); + V.push_back(VT2); + VTList.push_front(V); + N->setValueTypes(&(*VTList.begin())[0], 2); +} + /// SelectNodeTo - These are used for target selectors to *mutate* the /// specified node to have the specified return type, Target opcode, and @@ -1360,7 +1402,7 @@ SDOperand Op1, SDOperand Op2) { RemoveNodeFromCSEMaps(N); N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); - N->setValueTypes(VT1, VT2); + setNodeValueTypes(N, VT1, VT2); N->setOperands(Op1, Op2); } void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, @@ -1376,7 +1418,7 @@ SDOperand Op1, SDOperand Op2, SDOperand Op3) { RemoveNodeFromCSEMaps(N); N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); - N->setValueTypes(VT1, VT2); + setNodeValueTypes(N, VT1, VT2); N->setOperands(Op1, Op2, Op3); } @@ -1417,10 +1459,11 @@ // This node is about to morph, remove its old self from the CSE maps. RemoveNodeFromCSEMaps(U); - for (unsigned i = 0, e = U->getNumOperands(); i != e; ++i) - if (U->getOperand(i).Val == From) { + for (SDOperand *I = U->OperandList, *E = U->OperandList+U->NumOperands; + I != E; ++I) + if (I->Val == From) { From->removeUser(U); - U->Operands[i].Val = To; + I->Val = To; To->addUser(U); } @@ -1458,10 +1501,11 @@ // This node is about to morph, remove its old self from the CSE maps. RemoveNodeFromCSEMaps(U); - for (unsigned i = 0, e = U->getNumOperands(); i != e; ++i) - if (U->getOperand(i).Val == From) { + for (SDOperand *I = U->OperandList, *E = U->OperandList+U->NumOperands; + I != E; ++I) + if (I->Val == From) { From->removeUser(U); - U->Operands[i].Val = To; + I->Val = To; To->addUser(U); } @@ -1499,11 +1543,12 @@ // This node is about to morph, remove its old self from the CSE maps. RemoveNodeFromCSEMaps(U); - for (unsigned i = 0, e = U->getNumOperands(); i != e; ++i) - if (U->getOperand(i).Val == From) { - const SDOperand &ToOp = To[U->getOperand(i).ResNo]; + for (SDOperand *I = U->OperandList, *E = U->OperandList+U->NumOperands; + I != E; ++I) + if (I->Val == From) { + const SDOperand &ToOp = To[I->ResNo]; From->removeUser(U); - U->Operands[i] = ToOp; + *I = ToOp; ToOp.Val->addUser(U); } @@ -1523,6 +1568,15 @@ // SDNode Class //===----------------------------------------------------------------------===// + +/// getValueTypeList - Return a pointer to the specified value type. +/// +MVT::ValueType *SDNode::getValueTypeList(MVT::ValueType VT) { + static MVT::ValueType VTs[MVT::LAST_VALUETYPE]; + VTs[VT] = VT; + return &VTs[VT]; +} + /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the /// indicated value. This method ignores uses of other values defined by this /// operation. @@ -1570,6 +1624,7 @@ } case ISD::PCMARKER: return "PCMarker"; + case ISD::READCYCLECOUNTER: return "ReadCycleCounter"; case ISD::SRCVALUE: return "SrcValue"; case ISD::VALUETYPE: return "ValueType"; case ISD::EntryToken: return "EntryToken"; @@ -1586,6 +1641,7 @@ case ISD::BasicBlock: return "BasicBlock"; case ISD::Register: return "Register"; case ISD::ExternalSymbol: return "ExternalSymbol"; + case ISD::TargetExternalSymbol: return "TargetExternalSymbol"; case ISD::ConstantPool: return "ConstantPool"; case ISD::TargetConstantPool: return "TargetConstantPool"; case ISD::CopyToReg: return "CopyToReg"; @@ -1771,7 +1827,7 @@ } } -static void DumpNodes(SDNode *N, unsigned indent, const SelectionDAG *G) { +static void DumpNodes(const SDNode *N, unsigned indent, const SelectionDAG *G) { for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) if (N->getOperand(i).Val->hasOneUse()) DumpNodes(N->getOperand(i).Val, indent+2, G); @@ -1786,7 +1842,11 @@ void SelectionDAG::dump() const { std::cerr << "SelectionDAG has " << AllNodes.size() << " nodes:"; - std::vector Nodes(AllNodes); + std::vector Nodes; + for (allnodes_const_iterator I = allnodes_begin(), E = allnodes_end(); + I != E; ++I) + Nodes.push_back(I); + std::sort(Nodes.begin(), Nodes.end()); for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.88.2.1 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.88.2.2 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.88.2.1 Tue Oct 18 14:21:57 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Nov 16 12:32:15 2005 @@ -32,6 +32,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/Debug.h" #include #include @@ -45,7 +46,6 @@ static const bool ViewDAGs = 0; #endif - namespace llvm { //===--------------------------------------------------------------------===// /// FunctionLoweringInfo - This contains information that is global to a @@ -72,14 +72,6 @@ /// anywhere in the function. std::map StaticAllocaMap; - /// BlockLocalArguments - If any arguments are only used in a single basic - /// block, and if the target can access the arguments without side-effects, - /// avoid emitting CopyToReg nodes for those arguments. This map keeps - /// track of which arguments are local to each BB. - std::multimap > BlockLocalArguments; - - unsigned MakeReg(MVT::ValueType VT) { return RegMap->createVirtualRegister(TLI.getRegClassFor(VT)); } @@ -125,24 +117,39 @@ return false; } +/// isOnlyUsedInEntryBlock - If the specified argument is only used in the +/// entry block, return true. +static bool isOnlyUsedInEntryBlock(Argument *A) { + BasicBlock *Entry = A->getParent()->begin(); + for (Value::use_iterator UI = A->use_begin(), E = A->use_end(); UI != E; ++UI) + if (cast(*UI)->getParent() != Entry) + return false; // Use not in entry block. + return true; +} + FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli, Function &fn, MachineFunction &mf) : TLI(tli), Fn(fn), MF(mf), RegMap(MF.getSSARegMap()) { - // Initialize the mapping of values to registers. This is only set up for - // instruction values that are used outside of the block that defines - // them. + // Create a vreg for each argument register that is not dead and is used + // outside of the entry block for the function. for (Function::arg_iterator AI = Fn.arg_begin(), E = Fn.arg_end(); AI != E; ++AI) - InitializeRegForValue(AI); + if (!isOnlyUsedInEntryBlock(AI)) + InitializeRegForValue(AI); + // Initialize the mapping of values to registers. This is only set up for + // instruction values that are used outside of the block that defines + // them. Function::iterator BB = Fn.begin(), EB = Fn.end(); for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) if (AllocaInst *AI = dyn_cast(I)) if (ConstantUInt *CUI = dyn_cast(AI->getArraySize())) { const Type *Ty = AI->getAllocatedType(); uint64_t TySize = TLI.getTargetData().getTypeSize(Ty); - unsigned Align = TLI.getTargetData().getTypeAlignment(Ty); + unsigned Align = + std::max((unsigned)TLI.getTargetData().getTypeAlignment(Ty), + AI->getAlignment()); // If the alignment of the value is smaller than the size of the value, // and if the size of the value is particularly small (<= 8 bytes), @@ -151,9 +158,8 @@ // FIXME: This could be made better with a preferred alignment hook in // TargetData. It serves primarily to 8-byte align doubles for X86. if (Align < TySize && TySize <= 8) Align = TySize; - - if (CUI->getValue()) // Don't produce zero sized stack objects - TySize *= CUI->getValue(); // Get total allocated size. + TySize *= CUI->getValue(); // Get total allocated size. + if (TySize == 0) TySize = 1; // Don't create zero-sized stack objects. StaticAllocaMap[AI] = MF.getFrameInfo()->CreateStackObject((unsigned)TySize, Align); } @@ -399,6 +405,7 @@ void visitStore(StoreInst &I); void visitPHI(PHINode &I) { } // PHI nodes are handled specially. void visitCall(CallInst &I); + const char *visitIntrinsicCall(CallInst &I, unsigned Intrinsic); void visitVAStart(CallInst &I); void visitVAArg(VAArgInst &I); @@ -464,8 +471,8 @@ case MVT::f64: break; // No extension needed! } - - DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, getRoot(), Op1)); + // Allow targets to lower this further to meet ABI requirements + DAG.setRoot(TLI.LowerReturnTo(getRoot(), Op1, DAG)); } void SelectionDAGLowering::visitBr(BranchInst &I) { @@ -614,24 +621,47 @@ Ty = StTy->getElementType(Field); } else { Ty = cast(Ty)->getElementType(); - if (!isa(Idx) || !cast(Idx)->isNullValue()) { - // N = N + Idx * ElementSize; - uint64_t ElementSize = TD.getTypeSize(Ty); - SDOperand IdxN = getValue(Idx), Scale = getIntPtrConstant(ElementSize); - - // If the index is smaller or larger than intptr_t, truncate or extend - // it. - if (IdxN.getValueType() < Scale.getValueType()) { - if (Idx->getType()->isSigned()) - IdxN = DAG.getNode(ISD::SIGN_EXTEND, Scale.getValueType(), IdxN); - else - IdxN = DAG.getNode(ISD::ZERO_EXTEND, Scale.getValueType(), IdxN); - } else if (IdxN.getValueType() > Scale.getValueType()) - IdxN = DAG.getNode(ISD::TRUNCATE, Scale.getValueType(), IdxN); - IdxN = DAG.getNode(ISD::MUL, N.getValueType(), IdxN, Scale); + // If this is a constant subscript, handle it quickly. + if (ConstantInt *CI = dyn_cast(Idx)) { + if (CI->getRawValue() == 0) continue; + + uint64_t Offs; + if (ConstantSInt *CSI = dyn_cast(CI)) + Offs = (int64_t)TD.getTypeSize(Ty)*CSI->getValue(); + else + Offs = TD.getTypeSize(Ty)*cast(CI)->getValue(); + N = DAG.getNode(ISD::ADD, N.getValueType(), N, getIntPtrConstant(Offs)); + continue; + } + + // N = N + Idx * ElementSize; + uint64_t ElementSize = TD.getTypeSize(Ty); + SDOperand IdxN = getValue(Idx); + + // If the index is smaller or larger than intptr_t, truncate or extend + // it. + if (IdxN.getValueType() < N.getValueType()) { + if (Idx->getType()->isSigned()) + IdxN = DAG.getNode(ISD::SIGN_EXTEND, N.getValueType(), IdxN); + else + IdxN = DAG.getNode(ISD::ZERO_EXTEND, N.getValueType(), IdxN); + } else if (IdxN.getValueType() > N.getValueType()) + IdxN = DAG.getNode(ISD::TRUNCATE, N.getValueType(), IdxN); + + // If this is a multiply by a power of two, turn it into a shl + // immediately. This is a very common case. + if (isPowerOf2_64(ElementSize)) { + unsigned Amt = Log2_64(ElementSize); + IdxN = DAG.getNode(ISD::SHL, N.getValueType(), IdxN, + DAG.getConstant(Amt, TLI.getShiftAmountTy())); N = DAG.getNode(ISD::ADD, N.getValueType(), N, IdxN); + continue; } + + SDOperand Scale = getIntPtrConstant(ElementSize); + IdxN = DAG.getNode(ISD::MUL, N.getValueType(), IdxN, Scale); + N = DAG.getNode(ISD::ADD, N.getValueType(), N, IdxN); } } setValue(&I, N); @@ -645,7 +675,8 @@ const Type *Ty = I.getAllocatedType(); uint64_t TySize = TLI.getTargetData().getTypeSize(Ty); - unsigned Align = TLI.getTargetData().getTypeAlignment(Ty); + unsigned Align = std::max((unsigned)TLI.getTargetData().getTypeAlignment(Ty), + I.getAlignment()); SDOperand AllocSize = getValue(I.getArraySize()); MVT::ValueType IntPtr = TLI.getPointerTy(); @@ -719,123 +750,144 @@ DAG.getSrcValue(I.getOperand(1)))); } +/// visitIntrinsicCall - Lower the call to the specified intrinsic function. If +/// we want to emit this as a call to a named external function, return the name +/// otherwise lower it and return null. +const char * +SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { + switch (Intrinsic) { + case Intrinsic::vastart: visitVAStart(I); return 0; + case Intrinsic::vaend: visitVAEnd(I); return 0; + case Intrinsic::vacopy: visitVACopy(I); return 0; + case Intrinsic::returnaddress: visitFrameReturnAddress(I, false); return 0; + case Intrinsic::frameaddress: visitFrameReturnAddress(I, true); return 0; + case Intrinsic::setjmp: + return "_setjmp"+!TLI.usesUnderscoreSetJmpLongJmp(); + break; + case Intrinsic::longjmp: + return "_longjmp"+!TLI.usesUnderscoreSetJmpLongJmp(); + break; + case Intrinsic::memcpy: visitMemIntrinsic(I, ISD::MEMCPY); return 0; + case Intrinsic::memset: visitMemIntrinsic(I, ISD::MEMSET); return 0; + case Intrinsic::memmove: visitMemIntrinsic(I, ISD::MEMMOVE); return 0; + + case Intrinsic::readport: + case Intrinsic::readio: { + std::vector VTs; + VTs.push_back(TLI.getValueType(I.getType())); + VTs.push_back(MVT::Other); + std::vector Ops; + Ops.push_back(getRoot()); + Ops.push_back(getValue(I.getOperand(1))); + SDOperand Tmp = DAG.getNode(Intrinsic == Intrinsic::readport ? + ISD::READPORT : ISD::READIO, VTs, Ops); + + setValue(&I, Tmp); + DAG.setRoot(Tmp.getValue(1)); + return 0; + } + case Intrinsic::writeport: + case Intrinsic::writeio: + DAG.setRoot(DAG.getNode(Intrinsic == Intrinsic::writeport ? + ISD::WRITEPORT : ISD::WRITEIO, MVT::Other, + getRoot(), getValue(I.getOperand(1)), + getValue(I.getOperand(2)))); + return 0; + case Intrinsic::dbg_stoppoint: + case Intrinsic::dbg_region_start: + case Intrinsic::dbg_region_end: + case Intrinsic::dbg_func_start: + case Intrinsic::dbg_declare: + if (I.getType() != Type::VoidTy) + setValue(&I, DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType()))); + return 0; + + case Intrinsic::isunordered: + setValue(&I, DAG.getSetCC(MVT::i1,getValue(I.getOperand(1)), + getValue(I.getOperand(2)), ISD::SETUO)); + return 0; + + case Intrinsic::sqrt: + setValue(&I, DAG.getNode(ISD::FSQRT, + getValue(I.getOperand(1)).getValueType(), + getValue(I.getOperand(1)))); + return 0; + case Intrinsic::pcmarker: { + SDOperand Tmp = getValue(I.getOperand(1)); + DAG.setRoot(DAG.getNode(ISD::PCMARKER, MVT::Other, getRoot(), Tmp)); + return 0; + } + case Intrinsic::readcyclecounter: { + std::vector VTs; + VTs.push_back(MVT::i64); + VTs.push_back(MVT::Other); + std::vector Ops; + Ops.push_back(getRoot()); + SDOperand Tmp = DAG.getNode(ISD::READCYCLECOUNTER, VTs, Ops); + setValue(&I, Tmp); + DAG.setRoot(Tmp.getValue(1)); + return 0; + } + case Intrinsic::cttz: + setValue(&I, DAG.getNode(ISD::CTTZ, + getValue(I.getOperand(1)).getValueType(), + getValue(I.getOperand(1)))); + return 0; + case Intrinsic::ctlz: + setValue(&I, DAG.getNode(ISD::CTLZ, + getValue(I.getOperand(1)).getValueType(), + getValue(I.getOperand(1)))); + return 0; + case Intrinsic::ctpop: + setValue(&I, DAG.getNode(ISD::CTPOP, + getValue(I.getOperand(1)).getValueType(), + getValue(I.getOperand(1)))); + return 0; + default: + std::cerr << I; + assert(0 && "This intrinsic is not implemented yet!"); + return 0; + } +} + + void SelectionDAGLowering::visitCall(CallInst &I) { const char *RenameFn = 0; - SDOperand Tmp; - if (Function *F = I.getCalledFunction()) + if (Function *F = I.getCalledFunction()) { if (F->isExternal()) - switch (F->getIntrinsicID()) { - case 0: // Not an LLVM intrinsic. - if (F->getName() == "fabs" || F->getName() == "fabsf") { + if (unsigned IID = F->getIntrinsicID()) { + RenameFn = visitIntrinsicCall(I, IID); + if (!RenameFn) + return; + } else { // Not an LLVM intrinsic. + const std::string &Name = F->getName(); + if (Name[0] == 'f' && (Name == "fabs" || Name == "fabsf")) { if (I.getNumOperands() == 2 && // Basic sanity checks. I.getOperand(1)->getType()->isFloatingPoint() && I.getType() == I.getOperand(1)->getType()) { - Tmp = getValue(I.getOperand(1)); + SDOperand Tmp = getValue(I.getOperand(1)); setValue(&I, DAG.getNode(ISD::FABS, Tmp.getValueType(), Tmp)); return; } - } - else if (F->getName() == "sin" || F->getName() == "sinf") { + } else if (Name[0] == 's' && (Name == "sin" || Name == "sinf")) { if (I.getNumOperands() == 2 && // Basic sanity checks. I.getOperand(1)->getType()->isFloatingPoint() && I.getType() == I.getOperand(1)->getType()) { - Tmp = getValue(I.getOperand(1)); + SDOperand Tmp = getValue(I.getOperand(1)); setValue(&I, DAG.getNode(ISD::FSIN, Tmp.getValueType(), Tmp)); return; } - } - else if (F->getName() == "cos" || F->getName() == "cosf") { + } else if (Name[0] == 'c' && (Name == "cos" || Name == "cosf")) { if (I.getNumOperands() == 2 && // Basic sanity checks. I.getOperand(1)->getType()->isFloatingPoint() && I.getType() == I.getOperand(1)->getType()) { - Tmp = getValue(I.getOperand(1)); + SDOperand Tmp = getValue(I.getOperand(1)); setValue(&I, DAG.getNode(ISD::FCOS, Tmp.getValueType(), Tmp)); return; } } - break; - case Intrinsic::vastart: visitVAStart(I); return; - case Intrinsic::vaend: visitVAEnd(I); return; - case Intrinsic::vacopy: visitVACopy(I); return; - case Intrinsic::returnaddress: visitFrameReturnAddress(I, false); return; - case Intrinsic::frameaddress: visitFrameReturnAddress(I, true); return; - - case Intrinsic::setjmp: - RenameFn = "_setjmp"+!TLI.usesUnderscoreSetJmpLongJmp(); - break; - case Intrinsic::longjmp: - RenameFn = "_longjmp"+!TLI.usesUnderscoreSetJmpLongJmp(); - break; - case Intrinsic::memcpy: visitMemIntrinsic(I, ISD::MEMCPY); return; - case Intrinsic::memset: visitMemIntrinsic(I, ISD::MEMSET); return; - case Intrinsic::memmove: visitMemIntrinsic(I, ISD::MEMMOVE); return; - - case Intrinsic::readport: - case Intrinsic::readio: { - std::vector VTs; - VTs.push_back(TLI.getValueType(I.getType())); - VTs.push_back(MVT::Other); - std::vector Ops; - Ops.push_back(getRoot()); - Ops.push_back(getValue(I.getOperand(1))); - Tmp = DAG.getNode(F->getIntrinsicID() == Intrinsic::readport ? - ISD::READPORT : ISD::READIO, VTs, Ops); - - setValue(&I, Tmp); - DAG.setRoot(Tmp.getValue(1)); - return; - } - case Intrinsic::writeport: - case Intrinsic::writeio: - DAG.setRoot(DAG.getNode(F->getIntrinsicID() == Intrinsic::writeport ? - ISD::WRITEPORT : ISD::WRITEIO, MVT::Other, - getRoot(), getValue(I.getOperand(1)), - getValue(I.getOperand(2)))); - return; - case Intrinsic::dbg_stoppoint: - case Intrinsic::dbg_region_start: - case Intrinsic::dbg_region_end: - case Intrinsic::dbg_func_start: - case Intrinsic::dbg_declare: - if (I.getType() != Type::VoidTy) - setValue(&I, DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType()))); - return; - - case Intrinsic::isunordered: - setValue(&I, DAG.getSetCC(MVT::i1,getValue(I.getOperand(1)), - getValue(I.getOperand(2)), ISD::SETUO)); - return; - - case Intrinsic::sqrt: - setValue(&I, DAG.getNode(ISD::FSQRT, - getValue(I.getOperand(1)).getValueType(), - getValue(I.getOperand(1)))); - return; - - case Intrinsic::pcmarker: - Tmp = getValue(I.getOperand(1)); - DAG.setRoot(DAG.getNode(ISD::PCMARKER, MVT::Other, getRoot(), Tmp)); - return; - case Intrinsic::cttz: - setValue(&I, DAG.getNode(ISD::CTTZ, - getValue(I.getOperand(1)).getValueType(), - getValue(I.getOperand(1)))); - return; - case Intrinsic::ctlz: - setValue(&I, DAG.getNode(ISD::CTLZ, - getValue(I.getOperand(1)).getValueType(), - getValue(I.getOperand(1)))); - return; - case Intrinsic::ctpop: - setValue(&I, DAG.getNode(ISD::CTPOP, - getValue(I.getOperand(1)).getValueType(), - getValue(I.getOperand(1)))); - return; - default: - std::cerr << I; - assert(0 && "This intrinsic is not implemented yet!"); - return; } + } SDOperand Callee; if (!RenameFn) @@ -843,7 +895,7 @@ else Callee = DAG.getExternalSymbol(RenameFn, TLI.getPointerTy()); std::vector > Args; - + Args.reserve(I.getNumOperands()); for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) { Value *Arg = I.getOperand(i); SDOperand ArgNode = getValue(Arg); @@ -912,6 +964,11 @@ return 0; } +SDOperand TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, + SelectionDAG &DAG) { + return DAG.getNode(ISD::RET, MVT::Other, Chain, Op); +} + SDOperand TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, Value *VAListV, SelectionDAG &DAG) { @@ -1022,7 +1079,6 @@ // updates dom and loop info. } - bool SelectionDAGISel::runOnFunction(Function &Fn) { MachineFunction &MF = MachineFunction::construct(&Fn, TLI.getTargetMachine()); RegMap = MF.getSSARegMap(); @@ -1039,7 +1095,7 @@ if (isa(PN->getIncomingValue(i))) SplitCriticalEdge(PN->getIncomingBlock(i), BB); } - + FunctionLoweringInfo FuncInfo(TLI, Fn, MF); for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) @@ -1081,104 +1137,45 @@ } } -/// IsOnlyUsedInOneBasicBlock - If the specified argument is only used in a -/// single basic block, return that block. Otherwise, return a null pointer. -static BasicBlock *IsOnlyUsedInOneBasicBlock(Argument *A) { - if (A->use_empty()) return 0; - BasicBlock *BB = cast(A->use_back())->getParent(); - for (Argument::use_iterator UI = A->use_begin(), E = A->use_end(); UI != E; - ++UI) - if (isa(*UI) || cast(*UI)->getParent() != BB) - return 0; // Disagreement among the users? - - // Okay, there is a single BB user. Only permit this optimization if this is - // the entry block, otherwise, we might sink argument loads into loops and - // stuff. Later, when we have global instruction selection, this won't be an - // issue clearly. - if (BB == BB->getParent()->begin()) - return BB; - return 0; -} - void SelectionDAGISel:: LowerArguments(BasicBlock *BB, SelectionDAGLowering &SDL, std::vector &UnorderedChains) { // If this is the entry block, emit arguments. Function &F = *BB->getParent(); FunctionLoweringInfo &FuncInfo = SDL.FuncInfo; + SDOperand OldRoot = SDL.DAG.getRoot(); + std::vector Args = TLI.LowerArguments(F, SDL.DAG); - if (BB == &F.front()) { - SDOperand OldRoot = SDL.DAG.getRoot(); - - std::vector Args = TLI.LowerArguments(F, SDL.DAG); - - // If there were side effects accessing the argument list, do not do - // anything special. - if (OldRoot != SDL.DAG.getRoot()) { - unsigned a = 0; - for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end(); - AI != E; ++AI,++a) - if (!AI->use_empty()) { - SDL.setValue(AI, Args[a]); - - SDOperand Copy = - CopyValueToVirtualRegister(SDL, AI, FuncInfo.ValueMap[AI]); - UnorderedChains.push_back(Copy); - } - } else { - // Otherwise, if any argument is only accessed in a single basic block, - // emit that argument only to that basic block. - unsigned a = 0; - for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end(); - AI != E; ++AI,++a) - if (!AI->use_empty()) { - if (BasicBlock *BBU = IsOnlyUsedInOneBasicBlock(AI)) { - FuncInfo.BlockLocalArguments.insert(std::make_pair(BBU, - std::make_pair(AI, a))); - } else { - SDL.setValue(AI, Args[a]); - SDOperand Copy = - CopyValueToVirtualRegister(SDL, AI, FuncInfo.ValueMap[AI]); - UnorderedChains.push_back(Copy); - } - } - } - - // Next, if the function has live ins that need to be copied into vregs, - // emit the copies now, into the top of the block. - MachineFunction &MF = SDL.DAG.getMachineFunction(); - if (MF.livein_begin() != MF.livein_end()) { - SSARegMap *RegMap = MF.getSSARegMap(); - const MRegisterInfo &MRI = *MF.getTarget().getRegisterInfo(); - for (MachineFunction::livein_iterator LI = MF.livein_begin(), - E = MF.livein_end(); LI != E; ++LI) - if (LI->second) - MRI.copyRegToReg(*MF.begin(), MF.begin()->end(), LI->second, - LI->first, RegMap->getRegClass(LI->second)); - } + unsigned a = 0; + for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end(); + AI != E; ++AI, ++a) + if (!AI->use_empty()) { + SDL.setValue(AI, Args[a]); - // Finally, if the target has anything special to do, allow it to do so. - EmitFunctionEntryCode(F, SDL.DAG.getMachineFunction()); - } - - // See if there are any block-local arguments that need to be emitted in this - // block. - - if (!FuncInfo.BlockLocalArguments.empty()) { - std::multimap >::iterator BLAI = - FuncInfo.BlockLocalArguments.lower_bound(BB); - if (BLAI != FuncInfo.BlockLocalArguments.end() && BLAI->first == BB) { - // Lower the arguments into this block. - std::vector Args = TLI.LowerArguments(F, SDL.DAG); - - // Set up the value mapping for the local arguments. - for (; BLAI != FuncInfo.BlockLocalArguments.end() && BLAI->first == BB; - ++BLAI) - SDL.setValue(BLAI->second.first, Args[BLAI->second.second]); - - // Any dead arguments will just be ignored here. + // If this argument is live outside of the entry block, insert a copy from + // whereever we got it to the vreg that other BB's will reference it as. + if (FuncInfo.ValueMap.count(AI)) { + SDOperand Copy = + CopyValueToVirtualRegister(SDL, AI, FuncInfo.ValueMap[AI]); + UnorderedChains.push_back(Copy); + } } + + // Next, if the function has live ins that need to be copied into vregs, + // emit the copies now, into the top of the block. + MachineFunction &MF = SDL.DAG.getMachineFunction(); + if (MF.livein_begin() != MF.livein_end()) { + SSARegMap *RegMap = MF.getSSARegMap(); + const MRegisterInfo &MRI = *MF.getTarget().getRegisterInfo(); + for (MachineFunction::livein_iterator LI = MF.livein_begin(), + E = MF.livein_end(); LI != E; ++LI) + if (LI->second) + MRI.copyRegToReg(*MF.begin(), MF.begin()->end(), LI->second, + LI->first, RegMap->getRegClass(LI->second)); } + + // Finally, if the target has anything special to do, allow it to do so. + EmitFunctionEntryCode(F, SDL.DAG.getMachineFunction()); } @@ -1189,8 +1186,9 @@ std::vector UnorderedChains; - // Lower any arguments needed in this block. - LowerArguments(LLVMBB, SDL, UnorderedChains); + // Lower any arguments needed in this block if this is the entry block. + if (LLVMBB == &LLVMBB->getParent()->front()) + LowerArguments(LLVMBB, SDL, UnorderedChains); BB = FuncInfo.MBBMap[LLVMBB]; SDL.setCurrentBasicBlock(BB); @@ -1269,7 +1267,18 @@ // Turn all of the unordered chains into one factored node. if (!UnorderedChains.empty()) { - UnorderedChains.push_back(SDL.getRoot()); + SDOperand Root = SDL.getRoot(); + if (Root.getOpcode() != ISD::EntryToken) { + unsigned i = 0, e = UnorderedChains.size(); + for (; i != e; ++i) { + assert(UnorderedChains[i].Val->getNumOperands() > 1); + if (UnorderedChains[i].Val->getOperand(0) == Root) + break; // Don't add the root if we already indirectly depend on it. + } + + if (i == e) + UnorderedChains.push_back(Root); + } DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, UnorderedChains)); } From bocchino at cs.uiuc.edu Wed Nov 16 12:32:40 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:40 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/System/Unix/Process.inc Message-ID: <200511161832.MAA20966@zion.cs.uiuc.edu> Changes in directory llvm/lib/System/Unix: Process.inc updated: 1.11 -> 1.11.4.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+16 -10) Process.inc | 26 ++++++++++++++++---------- 1 files changed, 16 insertions(+), 10 deletions(-) Index: llvm/lib/System/Unix/Process.inc diff -u llvm/lib/System/Unix/Process.inc:1.11 llvm/lib/System/Unix/Process.inc:1.11.4.1 --- llvm/lib/System/Unix/Process.inc:1.11 Thu May 5 17:33:06 2005 +++ llvm/lib/System/Unix/Process.inc Wed Nov 16 12:32:28 2005 @@ -21,6 +21,9 @@ #ifdef HAVE_MALLOC_H #include #endif +#ifdef HAVE_MALLOC_MALLOC_H +#include +#endif //===----------------------------------------------------------------------===// //=== WARNING: Implementation here must contain only generic UNIX code that @@ -43,23 +46,22 @@ return static_cast(page_size); } -#if defined(HAVE_SBRK) -static char* som = reinterpret_cast(::sbrk(0)); -#endif - -size_t -Process::GetMallocUsage() -{ +size_t Process::GetMallocUsage() { #if defined(HAVE_MALLINFO) struct mallinfo mi; mi = ::mallinfo(); return mi.uordblks; +#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H) + malloc_statistics_t Stats; + malloc_zone_statistics(malloc_default_zone(), &Stats); + return Stats.size_in_use; // darwin #elif defined(HAVE_SBRK) // Note this is only an approximation and more closely resembles // the value returned by mallinfo in the arena field. - char * eom = (char*) sbrk(0); - if (eom != ((char*)-1) && som != ((char*)-1)) - return eom - som; + static char *StartOfMemory = reinterpret_cast(::sbrk(0)); + char *EndOfMemory = (char*)sbrk(0); + if (EndOfMemory != ((char*)-1) && StartOfMemory != ((char*)-1)) + return EndOfMemory - StartOfMemory; else return 0; #else @@ -74,6 +76,10 @@ #if defined(HAVE_MALLINFO) struct mallinfo mi = ::mallinfo(); return mi.uordblks + mi.hblkhd; +#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H) + malloc_statistics_t Stats; + malloc_zone_statistics(malloc_default_zone(), &Stats); + return Stats.size_allocated; // darwin #elif defined(HAVE_GETRUSAGE) struct rusage usage; ::getrusage(RUSAGE_SELF, &usage); From bocchino at cs.uiuc.edu Wed Nov 16 12:32:42 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:42 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Target/Makefile SubtargetFeature.cpp Target.td TargetLowering.cpp TargetSchedule.td TargetSelectionDAG.td Message-ID: <200511161832.MAA20989@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: Makefile updated: 1.24.4.1 -> 1.24.4.2 SubtargetFeature.cpp updated: 1.4 -> 1.4.2.1 Target.td updated: 1.52 -> 1.52.2.1 TargetLowering.cpp updated: 1.12 -> 1.12.2.1 TargetSchedule.td updated: 1.1 -> 1.1.2.1 TargetSelectionDAG.td updated: 1.3 -> 1.3.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+312 -80) Makefile | 1 SubtargetFeature.cpp | 231 +++++++++++++++++++++++++++++++++++--------------- Target.td | 50 ++++++++++ TargetLowering.cpp | 2 TargetSchedule.td | 19 +--- TargetSelectionDAG.td | 89 ++++++++++++++++++- 6 files changed, 312 insertions(+), 80 deletions(-) Index: llvm/lib/Target/Makefile diff -u llvm/lib/Target/Makefile:1.24.4.1 llvm/lib/Target/Makefile:1.24.4.2 --- llvm/lib/Target/Makefile:1.24.4.1 Tue Oct 18 14:21:57 2005 +++ llvm/lib/Target/Makefile Wed Nov 16 12:32:31 2005 @@ -6,6 +6,7 @@ # the University of Illinois Open Source License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## + LEVEL = ../.. LIBRARYNAME = LLVMTarget Index: llvm/lib/Target/SubtargetFeature.cpp diff -u llvm/lib/Target/SubtargetFeature.cpp:1.4 llvm/lib/Target/SubtargetFeature.cpp:1.4.2.1 --- llvm/lib/Target/SubtargetFeature.cpp:1.4 Wed Sep 7 00:44:14 2005 +++ llvm/lib/Target/SubtargetFeature.cpp Wed Nov 16 12:32:31 2005 @@ -12,18 +12,55 @@ //===----------------------------------------------------------------------===// #include "llvm/Target/SubtargetFeature.h" - -#include +#include "llvm/ADT/StringExtras.h" #include -#include #include #include - +#include using namespace llvm; -/// Splits a string of comma separated items in to a vector of strings. -void SubtargetFeatures::Split(std::vector &V, - const std::string &S) { +//===----------------------------------------------------------------------===// +// Static Helper Functions +//===----------------------------------------------------------------------===// + +/// hasFlag - Determine if a feature has a flag; '+' or '-' +/// +static inline bool hasFlag(const std::string &Feature) { + assert(!Feature.empty() && "Empty string"); + // Get first character + char Ch = Feature[0]; + // Check if first character is '+' or '-' flag + return Ch == '+' || Ch =='-'; +} + +/// StripFlag - Return string stripped of flag. +/// +static inline std::string StripFlag(const std::string &Feature) { + return hasFlag(Feature) ? Feature.substr(1) : Feature; +} + +/// isEnabled - Return true if enable flag; '+'. +/// +static inline bool isEnabled(const std::string &Feature) { + assert(!Feature.empty() && "Empty string"); + // Get first character + char Ch = Feature[0]; + // Check if first character is '+' for enabled + return Ch == '+'; +} + +/// PrependFlag - Return a string with a prepended flag; '+' or '-'. +/// +static inline std::string PrependFlag(const std::string &Feature, + bool IsEnabled) { + assert(!Feature.empty() && "Empty string"); + if (hasFlag(Feature)) return Feature; + return std::string(IsEnabled ? "+" : "-") + Feature; +} + +/// Split - Splits a string of comma separated items in to a vector of strings. +/// +static void Split(std::vector &V, const std::string &S) { // Start at beginning of string. size_t Pos = 0; while (true) { @@ -43,7 +80,8 @@ } /// Join a vector of strings to a string with a comma separating each element. -std::string SubtargetFeatures::Join(const std::vector &V) { +/// +static std::string Join(const std::vector &V) { // Start with empty string. std::string Result; // If the vector is not empty @@ -62,73 +100,108 @@ return Result; } -/// Convert a string to lowercase. -std::string SubtargetFeatures::toLower(const std::string &S) { - // Copy the string - std::string Result = S; - // For each character in string - for (size_t i = 0; i < Result.size(); i++) { - // Convert character to lowercase - Result[i] = std::tolower(Result[i]); - } - // Return the lowercased string - return Result; -} - /// Adding features. void SubtargetFeatures::AddFeature(const std::string &String, bool IsEnabled) { // Don't add empty features if (!String.empty()) { // Convert to lowercase, prepend flag and add to vector - Features.push_back(PrependFlag(toLower(String), IsEnabled)); + Features.push_back(PrependFlag(LowercaseString(String), IsEnabled)); } } -/// Find item in array using binary search. -const SubtargetFeatureKV * -SubtargetFeatures::Find(const std::string &S, - const SubtargetFeatureKV *A, size_t L) { +/// Find KV in array using binary search. +template const T *Find(const std::string &S, const T *A, size_t L) { // Determine the end of the array - const SubtargetFeatureKV *Hi = A + L; + const T *Hi = A + L; // Binary search the array - const SubtargetFeatureKV *F = std::lower_bound(A, Hi, S); + const T *F = std::lower_bound(A, Hi, S); // If not found then return NULL if (F == Hi || std::string(F->Key) != S) return NULL; // Return the found array item return F; } +/// getLongestEntryLength - Return the length of the longest entry in the table. +/// +static size_t getLongestEntryLength(const SubtargetFeatureKV *Table, + size_t Size) { + size_t MaxLen = 0; + for (size_t i = 0; i < Size; i++) + MaxLen = std::max(MaxLen, std::strlen(Table[i].Key)); + return MaxLen; +} + /// Display help for feature choices. -void SubtargetFeatures::Help(const char *Heading, - const SubtargetFeatureKV *Table, size_t TableSize) { - // Determine the length of the longest key - size_t MaxLen = 0; - for (size_t i = 0; i < TableSize; i++) - MaxLen = std::max(MaxLen, std::strlen(Table[i].Key)); - // Print heading - std::cerr << "Help for " << Heading << " choices\n\n"; - // For each feature - for (size_t i = 0; i < TableSize; i++) { - // Compute required padding - size_t Pad = MaxLen - std::strlen(Table[i].Key) + 1; - // Print details - std::cerr << Table[i].Key << std::string(Pad, ' ') << " - " - << Table[i].Desc << "\n"; - } - // Wrap it up - std::cerr << "\n\n"; - // Leave tool - exit(1); +/// +static void Help(const SubtargetFeatureKV *CPUTable, size_t CPUTableSize, + const SubtargetFeatureKV *FeatTable, size_t FeatTableSize) { + // Determine the length of the longest CPU and Feature entries. + unsigned MaxCPULen = getLongestEntryLength(CPUTable, CPUTableSize); + unsigned MaxFeatLen = getLongestEntryLength(FeatTable, FeatTableSize); + + // Print the CPU table. + std::cerr << "Available CPUs for this target:\n\n"; + for (size_t i = 0; i != CPUTableSize; i++) + std::cerr << " " << CPUTable[i].Key + << std::string(MaxCPULen - std::strlen(CPUTable[i].Key), ' ') + << " - " << CPUTable[i].Desc << ".\n"; + std::cerr << "\n"; + + // Print the Feature table. + std::cerr << "Available features for this target:\n\n"; + for (size_t i = 0; i != FeatTableSize; i++) + std::cerr << " " << FeatTable[i].Key + << std::string(MaxFeatLen - std::strlen(FeatTable[i].Key), ' ') + << " - " << FeatTable[i].Desc << ".\n"; + std::cerr << "\n"; + + std::cerr << "Use +feature to enable a feature, or -feature to disable it.\n" + << "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n"; + exit(1); } -/// Parse feature string for quick usage. -uint32_t SubtargetFeatures::Parse(const std::string &String, - const std::string &DefaultCPU, - const SubtargetFeatureKV *CPUTable, - size_t CPUTableSize, - const SubtargetFeatureKV *FeatureTable, - size_t FeatureTableSize) { +//===----------------------------------------------------------------------===// +// SubtargetFeatures Implementation +//===----------------------------------------------------------------------===// + +SubtargetFeatures::SubtargetFeatures(const std::string &Initial) { + // Break up string into separate features + Split(Features, Initial); +} + + +std::string SubtargetFeatures::getString() const { + return Join(Features); +} +void SubtargetFeatures::setString(const std::string &Initial) { + // Throw out old features + Features.clear(); + // Break up string into separate features + Split(Features, LowercaseString(Initial)); +} + + +/// setCPU - Set the CPU string. Replaces previous setting. Setting to "" +/// clears CPU. +void SubtargetFeatures::setCPU(const std::string &String) { + Features[0] = LowercaseString(String); +} + + +/// setCPUIfNone - Setting CPU string only if no string is set. +/// +void SubtargetFeatures::setCPUIfNone(const std::string &String) { + if (Features[0].empty()) setCPU(String); +} + + +/// getBits - Get feature bits. +/// +uint32_t SubtargetFeatures::getBits(const SubtargetFeatureKV *CPUTable, + size_t CPUTableSize, + const SubtargetFeatureKV *FeatureTable, + size_t FeatureTableSize) { assert(CPUTable && "missing CPU table"); assert(FeatureTable && "missing features table"); #ifndef NDEBUG @@ -141,14 +214,12 @@ "CPU features table is not sorted"); } #endif - std::vector Features; // Subtarget features as a vector uint32_t Bits = 0; // Resulting bits - // Split up features - Split(Features, String); - // Check if default is needed - if (Features[0].empty()) Features[0] = DefaultCPU; - // Check for help - if (Features[0] == "help") Help("CPU", CPUTable, CPUTableSize); + + // Check if help is needed + if (Features[0] == "help") + Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize); + // Find CPU entry const SubtargetFeatureKV *CPUEntry = Find(Features[0], CPUTable, CPUTableSize); @@ -164,10 +235,12 @@ } // Iterate through each feature for (size_t i = 1; i < Features.size(); i++) { - // Get next feature const std::string &Feature = Features[i]; + // Check for help - if (Feature == "+help") Help("feature", FeatureTable, FeatureTableSize); + if (Feature == "+help") + Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize); + // Find feature in table. const SubtargetFeatureKV *FeatureEntry = Find(StripFlag(Feature), FeatureTable, FeatureTableSize); @@ -186,7 +259,32 @@ return Bits; } -/// Print feature string. +/// Get info pointer +void *SubtargetFeatures::getInfo(const SubtargetInfoKV *Table, + size_t TableSize) { + assert(Table && "missing table"); +#ifndef NDEBUG + for (size_t i = 1; i < TableSize; i++) { + assert(strcmp(Table[i - 1].Key, Table[i].Key) < 0 && "Table is not sorted"); + } +#endif + + // Find entry + const SubtargetInfoKV *Entry = Find(Features[0], Table, TableSize); + + if (Entry) { + return Entry->Value; + } else { + std::cerr << "'" << Features[0] + << "' is not a recognized processor for this target" + << " (ignoring processor)" + << "\n"; + return NULL; + } +} + +/// print - Print feature string. +/// void SubtargetFeatures::print(std::ostream &OS) const { for (size_t i = 0; i < Features.size(); i++) { OS << Features[i] << " "; @@ -194,7 +292,8 @@ OS << "\n"; } -/// Dump feature info. +/// dump - Dump feature info. +/// void SubtargetFeatures::dump() const { print(std::cerr); } Index: llvm/lib/Target/Target.td diff -u llvm/lib/Target/Target.td:1.52 llvm/lib/Target/Target.td:1.52.2.1 --- llvm/lib/Target/Target.td:1.52 Mon Oct 10 01:00:30 2005 +++ llvm/lib/Target/Target.td Wed Nov 16 12:32:31 2005 @@ -113,6 +113,12 @@ //===----------------------------------------------------------------------===// +// Pull in the common support for scheduling +// +include "../TargetSchedule.td" + + +//===----------------------------------------------------------------------===// // Instruction set description - These classes correspond to the C++ classes in // the Target/TargetInstrInfo.h file. // @@ -147,6 +153,8 @@ bit isTerminator = 0; // Is this part of the terminator for a basic block? bit hasDelaySlot = 0; // Does this instruction have an delay slot? bit usesCustomDAGSchedInserter = 0; // Pseudo instr needing special help. + + InstrItinClass Itinerary; // Execution steps used for scheduling. } @@ -242,6 +250,48 @@ } //===----------------------------------------------------------------------===// +// SubtargetFeature - A characteristic of the chip set. +// +class SubtargetFeature { + // Name - Feature name. Used by command line (-mattr=) to determine the + // appropriate target chip. + // + string Name = n; + + // Type - Type of attribute to be set by feature. + // + string Type = t; + + // Attribute - Attribute to be set by feature. + // + string Attribute = a; + + // Desc - Feature description. Used by command line (-mattr=) to display help + // information. + // + string Desc = d; +} + +//===----------------------------------------------------------------------===// +// Processor chip sets - These values represent each of the chip sets supported +// by the scheduler. Each Processor definition requires corresponding +// instruction itineraries. +// +class Processor f> { + // Name - Chip set name. Used by command line (-mcpu=) to determine the + // appropriate target chip. + // + string Name = n; + + // ProcItin - The scheduling information for the target processor. + // + ProcessorItineraries ProcItin = pi; + + // Features - list of + list Features = f; +} + +//===----------------------------------------------------------------------===// // Pull in the common support for DAG isel generation // include "../TargetSelectionDAG.td" Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.12 llvm/lib/Target/TargetLowering.cpp:1.12.2.1 --- llvm/lib/Target/TargetLowering.cpp:1.12 Tue Sep 27 17:13:56 2005 +++ llvm/lib/Target/TargetLowering.cpp Wed Nov 16 12:32:31 2005 @@ -30,6 +30,8 @@ maxStoresPerMemSet = maxStoresPerMemCpy = maxStoresPerMemMove = 8; allowUnalignedMemoryAccesses = false; UseUnderscoreSetJmpLongJmp = false; + IntDivIsCheap = false; + Pow2DivIsCheap = false; } TargetLowering::~TargetLowering() {} Index: llvm/lib/Target/TargetSchedule.td diff -u llvm/lib/Target/TargetSchedule.td:1.1 llvm/lib/Target/TargetSchedule.td:1.1.2.1 --- llvm/lib/Target/TargetSchedule.td:1.1 Tue Oct 18 11:23:40 2005 +++ llvm/lib/Target/TargetSchedule.td Wed Nov 16 12:32:31 2005 @@ -13,13 +13,6 @@ //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// -// Processor chip sets - These values represent each of the chip sets supported -// by the scheduler. Each Processor definition requires corresponding -// instruction itineraries. -// -class Processor; - -//===----------------------------------------------------------------------===// // Processor functional unit - These values represent the function units // available across all chip sets for the target. Eg., IntUnit, FPUnit, ... // These may be independent values for each chip set or may be shared across @@ -35,8 +28,8 @@ // need to complete the stage. Units represent the choice of functional units // that can be used to complete the stage. Eg. IntUnit1, IntUnit2. // -class InstrStage units> { - int Latency = latency; // length of stage in machine cycles +class InstrStage units> { + int Cycles = cycles; // length of stage in machine cycles list Units = units; // choice of functional units } @@ -68,7 +61,11 @@ // Processor itineraries - These values represent the set of all itinerary // classes for a given chip set. // -class ProcessorItineraries iid> { - Processor Proc = proc; +class ProcessorItineraries iid> { list IID = iid; } + +// NoItineraries - A marker that can be used by processors without schedule +// info. +def NoItineraries : ProcessorItineraries<[]>; + Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.3 llvm/lib/Target/TargetSelectionDAG.td:1.3.2.1 --- llvm/lib/Target/TargetSelectionDAG.td:1.3 Fri Oct 14 01:40:20 2005 +++ llvm/lib/Target/TargetSelectionDAG.td Wed Nov 16 12:32:31 2005 @@ -68,7 +68,8 @@ // Builtin profiles. def SDTImm : SDTypeProfile<1, 0, [SDTCisInt<0>]>; // for 'imm'. -def SDTVT : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt' +def SDTVT : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt'. +def SDTUNDEF : SDTypeProfile<1, 0, []>; // for 'undef'. def SDTIntBinOp : SDTypeProfile<1, 2, [ // add, and, or, xor, udiv, etc. SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0> ]>; @@ -93,11 +94,25 @@ def SDTFPExtendOp : SDTypeProfile<1, 1, [ // fextend SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0> ]>; +def SDTIntToFPOp : SDTypeProfile<1, 1, [ // [su]int_to_fp + SDTCisFP<0>, SDTCisInt<1> +]>; +def SDTFPToIntOp : SDTypeProfile<1, 1, [ // fp_to_[su]int + SDTCisInt<0>, SDTCisFP<1> +]>; def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>, SDTCisVTSmallerThanOp<2, 1> ]>; +def SDTSetCC : SDTypeProfile<1, 3, [ // setcc + SDTCisInt<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT> +]>; + +def SDTSelect : SDTypeProfile<1, 3, [ // select + SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3> +]>; + //===----------------------------------------------------------------------===// // Selection DAG Node Properties. // @@ -123,6 +138,8 @@ def imm : SDNode<"ISD::Constant" , SDTImm , [], "ConstantSDNode">; def vt : SDNode<"ISD::VALUETYPE" , SDTVT , [], "VTSDNode">; +def cond : SDNode<"ISD::CONDCODE" , SDTVT , [], "CondCodeSDNode">; +def undef : SDNode<"ISD::UNDEF" , SDTUNDEF , []>; def add : SDNode<"ISD::ADD" , SDTIntBinOp , [SDNPCommutative, SDNPAssociative]>; def sub : SDNode<"ISD::SUB" , SDTIntBinOp>; @@ -146,6 +163,8 @@ def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>; +def cttz : SDNode<"ISD::CTTZ" , SDTIntUnaryOp>; +def ctpop : SDNode<"ISD::CTPOP" , SDTIntUnaryOp>; def sext : SDNode<"ISD::SIGN_EXTEND", SDTIntExtendOp>; def zext : SDNode<"ISD::ZERO_EXTEND", SDTIntExtendOp>; def anyext : SDNode<"ISD::ANY_EXTEND" , SDTIntExtendOp>; @@ -163,6 +182,28 @@ def fround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>; def fextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>; +def sint_to_fp : SDNode<"ISD::SINT_TO_FP" , SDTIntToFPOp>; +def uint_to_fp : SDNode<"ISD::UINT_TO_FP" , SDTIntToFPOp>; +def fp_to_sint : SDNode<"ISD::FP_TO_SINT" , SDTFPToIntOp>; +def fp_to_uint : SDNode<"ISD::FP_TO_UINT" , SDTFPToIntOp>; + +def setcc : SDNode<"ISD::SETCC" , SDTSetCC>; +def select : SDNode<"ISD::SELECT" , SDTSelect>; + +//===----------------------------------------------------------------------===// +// Selection DAG Condition Codes + +class CondCode; // ISD::CondCode enums +def SETOEQ : CondCode; def SETOGT : CondCode; +def SETOGE : CondCode; def SETOLT : CondCode; def SETOLE : CondCode; +def SETONE : CondCode; def SETO : CondCode; def SETUO : CondCode; +def SETUEQ : CondCode; def SETUGT : CondCode; def SETUGE : CondCode; +def SETULT : CondCode; def SETULE : CondCode; def SETUNE : CondCode; + +def SETEQ : CondCode; def SETGT : CondCode; def SETGE : CondCode; +def SETLT : CondCode; def SETLE : CondCode; def SETNE : CondCode; + + //===----------------------------------------------------------------------===// // Selection DAG Node Transformation Functions. // @@ -206,7 +247,6 @@ // Leaf fragments. def immAllOnes : PatLeaf<(imm), [{ return N->isAllOnesValue(); }]>; -def immZero : PatLeaf<(imm), [{ return N->isNullValue(); }]>; def vtInt : PatLeaf<(vt), [{ return MVT::isInteger(N->getVT()); }]>; def vtFP : PatLeaf<(vt), [{ return MVT::isFloatingPoint(N->getVT()); }]>; @@ -214,7 +254,50 @@ // Other helper fragments. def not : PatFrag<(ops node:$in), (xor node:$in, immAllOnes)>; -def ineg : PatFrag<(ops node:$in), (sub immZero, node:$in)>; +def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>; + + +// setcc convenience fragments. +def setoeq : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETOEQ)>; +def setogt : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETOGT)>; +def setoge : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETOGE)>; +def setolt : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETOLT)>; +def setole : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETOLE)>; +def setone : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETONE)>; +def seto : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETO)>; +def setuo : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETUO)>; +def setueq : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETUEQ)>; +def setugt : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETUGT)>; +def setuge : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETUGE)>; +def setult : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETULT)>; +def setule : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETULE)>; +def setune : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETUNE)>; +def seteq : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETEQ)>; +def setgt : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETGT)>; +def setge : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETGE)>; +def setlt : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETLT)>; +def setle : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETLE)>; +def setne : PatFrag<(ops node:$lhs, node:$rhs), + (setcc node:$lhs, node:$rhs, SETNE)>; //===----------------------------------------------------------------------===// // Selection DAG Pattern Support. From bocchino at cs.uiuc.edu Wed Nov 16 12:32:46 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:46 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Target/CBackend/AltiVecCTargetMachine.h AltiVecWriter.cpp CTargetMachine.h SSECTargetMachine.h SSEWriter.cpp Writer.cpp Message-ID: <200511161832.MAA21054@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/CBackend: AltiVecCTargetMachine.h updated: 1.1.2.1 -> 1.1.2.2 AltiVecWriter.cpp updated: 1.1.2.1 -> 1.1.2.2 CTargetMachine.h updated: 1.8.2.1 -> 1.8.2.2 SSECTargetMachine.h updated: 1.1.2.1 -> 1.1.2.2 SSEWriter.cpp updated: 1.1.2.1 -> 1.1.2.2 Writer.cpp updated: 1.245.2.1 -> 1.245.2.2 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+10 -8) AltiVecCTargetMachine.h | 2 +- AltiVecWriter.cpp | 2 +- CTargetMachine.h | 2 +- SSECTargetMachine.h | 2 +- SSEWriter.cpp | 2 +- Writer.cpp | 8 +++++--- 6 files changed, 10 insertions(+), 8 deletions(-) Index: llvm/lib/Target/CBackend/AltiVecCTargetMachine.h diff -u llvm/lib/Target/CBackend/AltiVecCTargetMachine.h:1.1.2.1 llvm/lib/Target/CBackend/AltiVecCTargetMachine.h:1.1.2.2 --- llvm/lib/Target/CBackend/AltiVecCTargetMachine.h:1.1.2.1 Tue Oct 18 14:36:52 2005 +++ llvm/lib/Target/CBackend/AltiVecCTargetMachine.h Wed Nov 16 12:32:34 2005 @@ -26,7 +26,7 @@ // This is the only thing that actually does anything here. bool addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType); + CodeGenFileType FileType, bool Fast); }; Index: llvm/lib/Target/CBackend/AltiVecWriter.cpp diff -u llvm/lib/Target/CBackend/AltiVecWriter.cpp:1.1.2.1 llvm/lib/Target/CBackend/AltiVecWriter.cpp:1.1.2.2 --- llvm/lib/Target/CBackend/AltiVecWriter.cpp:1.1.2.1 Tue Oct 18 14:36:52 2005 +++ llvm/lib/Target/CBackend/AltiVecWriter.cpp Wed Nov 16 12:32:34 2005 @@ -193,7 +193,7 @@ //===----------------------------------------------------------------------===// bool AltiVecCTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &o, - CodeGenFileType FileType) { + CodeGenFileType FileType, bool Fast) { if (FileType != TargetMachine::AssemblyFile) return true; // Add lowervectors pass here to lower variable-length vectors, which we can't handle PM.add(createLowerGCPass()); Index: llvm/lib/Target/CBackend/CTargetMachine.h diff -u llvm/lib/Target/CBackend/CTargetMachine.h:1.8.2.1 llvm/lib/Target/CBackend/CTargetMachine.h:1.8.2.2 --- llvm/lib/Target/CBackend/CTargetMachine.h:1.8.2.1 Tue Oct 18 14:21:57 2005 +++ llvm/lib/Target/CBackend/CTargetMachine.h Wed Nov 16 12:32:34 2005 @@ -25,7 +25,7 @@ // This is the only thing that actually does anything here. virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType); + CodeGenFileType FileType, bool Fast); // This class always works, but shouldn't be the default in most cases. static unsigned getModuleMatchQuality(const Module &M) { return 1; } Index: llvm/lib/Target/CBackend/SSECTargetMachine.h diff -u llvm/lib/Target/CBackend/SSECTargetMachine.h:1.1.2.1 llvm/lib/Target/CBackend/SSECTargetMachine.h:1.1.2.2 --- llvm/lib/Target/CBackend/SSECTargetMachine.h:1.1.2.1 Tue Oct 18 14:36:52 2005 +++ llvm/lib/Target/CBackend/SSECTargetMachine.h Wed Nov 16 12:32:34 2005 @@ -26,7 +26,7 @@ // This is the only thing that actually does anything here. bool addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType); + CodeGenFileType FileType, bool Fast); }; Index: llvm/lib/Target/CBackend/SSEWriter.cpp diff -u llvm/lib/Target/CBackend/SSEWriter.cpp:1.1.2.1 llvm/lib/Target/CBackend/SSEWriter.cpp:1.1.2.2 --- llvm/lib/Target/CBackend/SSEWriter.cpp:1.1.2.1 Tue Oct 18 14:36:52 2005 +++ llvm/lib/Target/CBackend/SSEWriter.cpp Wed Nov 16 12:32:34 2005 @@ -117,7 +117,7 @@ //===----------------------------------------------------------------------===// bool SSECTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &o, - CodeGenFileType FileType) { + CodeGenFileType FileType, bool Fast) { if (FileType != TargetMachine::AssemblyFile) return true; // Add lowervectors pass here to lower variable-length vectors, which we can't handle PM.add(createLowerGCPass()); Index: llvm/lib/Target/CBackend/Writer.cpp diff -u llvm/lib/Target/CBackend/Writer.cpp:1.245.2.1 llvm/lib/Target/CBackend/Writer.cpp:1.245.2.2 --- llvm/lib/Target/CBackend/Writer.cpp:1.245.2.1 Tue Oct 18 14:21:57 2005 +++ llvm/lib/Target/CBackend/Writer.cpp Wed Nov 16 12:32:34 2005 @@ -662,6 +662,7 @@ // Ensure that all structure types have names... Mang = new Mangler(M); + Mang->markCharUnacceptable('.'); // get declaration for alloca Out << "/* Provide Declarations */\n"; @@ -835,7 +836,7 @@ Out << "/* Structure forward decls */\n"; for (; I != End; ++I) if (const Type *STy = dyn_cast(I->second)) { - std::string Name = "struct l_" + Mangler::makeNameProper(I->first); + std::string Name = "struct l_" + Mang->makeNameProper(I->first); Out << Name << ";\n"; TypeNames.insert(std::make_pair(STy, Name)); } @@ -846,7 +847,7 @@ Out << "/* Typedefs */\n"; for (I = ST.type_begin(); I != End; ++I) { const Type *Ty = cast(I->second); - std::string Name = "l_" + Mangler::makeNameProper(I->first); + std::string Name = "l_" + Mang->makeNameProper(I->first); Out << "typedef "; printType(Out, Ty, Name); Out << ";\n"; @@ -1546,12 +1547,13 @@ //===----------------------------------------------------------------------===// bool CTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &o, - CodeGenFileType FileType) { + CodeGenFileType FileType, bool Fast) { if (FileType != TargetMachine::AssemblyFile) return true; PM.add(createLowerGCPass()); PM.add(createLowerAllocationsPass(true)); PM.add(createLowerInvokePass()); + PM.add(createCFGSimplificationPass()); // clean up after lower invoke. PM.add(new CBackendNameAllUsedStructs()); PM.add(new CWriter(o, getIntrinsicLowering())); return false; From bocchino at cs.uiuc.edu Wed Nov 16 12:32:53 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:53 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp SparcV9TargetMachine.h Message-ID: <200511161832.MAA21180@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9TargetMachine.cpp updated: 1.142 -> 1.142.2.1 SparcV9TargetMachine.h updated: 1.14 -> 1.14.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+9 -8) SparcV9TargetMachine.cpp | 15 ++++++++------- SparcV9TargetMachine.h | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) Index: llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp diff -u llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.142 llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.142.2.1 --- llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.142 Thu Sep 1 16:38:21 2005 +++ llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp Wed Nov 16 12:32:42 2005 @@ -162,7 +162,8 @@ /// bool SparcV9TargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType) { + CodeGenFileType FileType, + bool Fast) { if (FileType != TargetMachine::AssemblyFile) return true; // FIXME: Implement efficient support for garbage collection intrinsics. @@ -171,12 +172,12 @@ // Replace malloc and free instructions with library calls. PM.add(createLowerAllocationsPass()); - // FIXME: implement the switch instruction in the instruction selector. - PM.add(createLowerSwitchPass()); - // FIXME: implement the invoke/unwind instructions! PM.add(createLowerInvokePass()); + // FIXME: implement the switch instruction in the instruction selector. + PM.add(createLowerSwitchPass()); + // decompose multi-dimensional array references into single-dim refs PM.add(createDecomposeMultiDimRefsPass()); @@ -262,12 +263,12 @@ // Replace malloc and free instructions with library calls. PM.add(createLowerAllocationsPass()); - // FIXME: implement the switch instruction in the instruction selector. - PM.add(createLowerSwitchPass()); - // FIXME: implement the invoke/unwind instructions! PM.add(createLowerInvokePass()); + // FIXME: implement the switch instruction in the instruction selector. + PM.add(createLowerSwitchPass()); + // decompose multi-dimensional array references into single-dim refs PM.add(createDecomposeMultiDimRefsPass()); Index: llvm/lib/Target/SparcV9/SparcV9TargetMachine.h diff -u llvm/lib/Target/SparcV9/SparcV9TargetMachine.h:1.14 llvm/lib/Target/SparcV9/SparcV9TargetMachine.h:1.14.2.1 --- llvm/lib/Target/SparcV9/SparcV9TargetMachine.h:1.14 Thu Sep 1 16:38:21 2005 +++ llvm/lib/Target/SparcV9/SparcV9TargetMachine.h Wed Nov 16 12:32:42 2005 @@ -45,7 +45,7 @@ } virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType); + CodeGenFileType FileType, bool Fast); virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM, MachineCodeEmitter &MCE); From bocchino at cs.uiuc.edu Wed Nov 16 12:32:51 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:51 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Target/Skeleton/SkeletonTargetMachine.cpp SkeletonTargetMachine.h Message-ID: <200511161832.MAA21154@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Skeleton: SkeletonTargetMachine.cpp updated: 1.5 -> 1.5.2.1 SkeletonTargetMachine.h updated: 1.4 -> 1.4.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+3 -2) SkeletonTargetMachine.cpp | 3 ++- SkeletonTargetMachine.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/Target/Skeleton/SkeletonTargetMachine.cpp diff -u llvm/lib/Target/Skeleton/SkeletonTargetMachine.cpp:1.5 llvm/lib/Target/Skeleton/SkeletonTargetMachine.cpp:1.5.2.1 --- llvm/lib/Target/Skeleton/SkeletonTargetMachine.cpp:1.5 Thu Sep 1 16:38:21 2005 +++ llvm/lib/Target/Skeleton/SkeletonTargetMachine.cpp Wed Nov 16 12:32:39 2005 @@ -40,7 +40,8 @@ /// bool SkeletonTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType) { + CodeGenFileType FileType, + bool Fast) { if (FileType != TargetMachine::AssemblyFile) return true; // PM.add(createRegisterAllocator()); Index: llvm/lib/Target/Skeleton/SkeletonTargetMachine.h diff -u llvm/lib/Target/Skeleton/SkeletonTargetMachine.h:1.4 llvm/lib/Target/Skeleton/SkeletonTargetMachine.h:1.4.2.1 --- llvm/lib/Target/Skeleton/SkeletonTargetMachine.h:1.4 Thu Sep 1 16:38:21 2005 +++ llvm/lib/Target/Skeleton/SkeletonTargetMachine.h Wed Nov 16 12:32:39 2005 @@ -44,7 +44,7 @@ MachineCodeEmitter &MCE); virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType); + CodeGenFileType FileType, bool Fast); }; } // end namespace llvm From bocchino at cs.uiuc.edu Wed Nov 16 12:32:47 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:47 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Target/IA64/IA64.h IA64AsmPrinter.cpp IA64ISelDAGToDAG.cpp IA64ISelLowering.cpp IA64ISelLowering.h IA64ISelPattern.cpp IA64InstrFormats.td IA64InstrInfo.td IA64RegisterInfo.cpp IA64RegisterInfo.td IA64TargetMachine.cpp IA64TargetMachine.h Makefile README Message-ID: <200511161832.MAA21087@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64.h updated: 1.2 -> 1.2.4.1 IA64AsmPrinter.cpp updated: 1.12 -> 1.12.4.1 IA64ISelDAGToDAG.cpp added (r1.10.2.2) IA64ISelLowering.cpp added (r1.3.2.2) IA64ISelLowering.h added (r1.1.4.2) IA64ISelPattern.cpp updated: 1.66 -> 1.66.2.1 IA64InstrFormats.td updated: 1.1 -> 1.1.4.1 IA64InstrInfo.td updated: 1.15 -> 1.15.2.1 IA64RegisterInfo.cpp updated: 1.7 -> 1.7.2.1 IA64RegisterInfo.td updated: 1.8 -> 1.8.2.1 IA64TargetMachine.cpp updated: 1.5 -> 1.5.2.1 IA64TargetMachine.h updated: 1.4 -> 1.4.2.1 Makefile updated: 1.3 -> 1.3.4.1 README updated: 1.4 -> 1.4.4.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+1578 -184) IA64.h | 5 IA64AsmPrinter.cpp | 22 + IA64ISelDAGToDAG.cpp | 556 +++++++++++++++++++++++++++++++++++++++++++++ IA64ISelLowering.cpp | 367 +++++++++++++++++++++++++++++ IA64ISelLowering.h | 88 +++++++ IA64ISelPattern.cpp | 16 - IA64InstrFormats.td | 12 IA64InstrInfo.td | 613 ++++++++++++++++++++++++++++++++++++++------------ IA64RegisterInfo.cpp | 27 -- IA64RegisterInfo.td | 30 +- IA64TargetMachine.cpp | 17 + IA64TargetMachine.h | 2 Makefile | 3 README | 4 14 files changed, 1578 insertions(+), 184 deletions(-) Index: llvm/lib/Target/IA64/IA64.h diff -u llvm/lib/Target/IA64/IA64.h:1.2 llvm/lib/Target/IA64/IA64.h:1.2.4.1 --- llvm/lib/Target/IA64/IA64.h:1.2 Thu Apr 21 18:13:10 2005 +++ llvm/lib/Target/IA64/IA64.h Wed Nov 16 12:32:35 2005 @@ -22,6 +22,11 @@ class FunctionPass; class IntrinsicLowering; +/// createIA64DAGToDAGInstructionSelector - This pass converts an LLVM +/// function into IA64 machine code in a sane, DAG->DAG transform. +/// +FunctionPass *createIA64DAGToDAGInstructionSelector(TargetMachine &TM); + /// createIA64PatternInstructionSelector - This pass converts an LLVM function /// into a machine code representation in a more aggressive way. /// Index: llvm/lib/Target/IA64/IA64AsmPrinter.cpp diff -u llvm/lib/Target/IA64/IA64AsmPrinter.cpp:1.12 llvm/lib/Target/IA64/IA64AsmPrinter.cpp:1.12.4.1 --- llvm/lib/Target/IA64/IA64AsmPrinter.cpp:1.12 Fri Apr 22 12:54:15 2005 +++ llvm/lib/Target/IA64/IA64AsmPrinter.cpp Wed Nov 16 12:32:35 2005 @@ -11,7 +11,7 @@ // of machine-dependent LLVM code to assembly accepted by the GNU binutils 'gas' // assembler. The Intel 'ias' and HP-UX 'as' assemblers *may* choke on this // output, but if so that's a bug I'd like to hear about: please file a bug -// report in bugzilla. FYI, the excellent 'ias' assembler is bundled with +// report in bugzilla. FYI, the not too bad 'ias' assembler is bundled with // the Intel C/C++ compiler for Itanium Linux. // //===----------------------------------------------------------------------===// @@ -249,7 +249,25 @@ } void printS64ImmOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT) { - O << (int64_t)MI->getOperand(OpNo).getImmedValue(); +// XXX : nasty hack to avoid GPREL22 "relocation truncated to fit" linker +// errors - instead of add rX = @gprel(CPI), r1;; we now +// emit movl rX = @gprel(CPIgetOperand(OpNo).isImmediate()) { + O << (int64_t)MI->getOperand(OpNo).getImmedValue(); + } else { // this is a constant pool reference: FIXME: assert this + printOp(MI->getOperand(OpNo)); + } + } + + void printGlobalOperand(const MachineInstr *MI, unsigned OpNo, + MVT::ValueType VT) { + printOp(MI->getOperand(OpNo), false); // this is NOT a br.call instruction } void printCallOperand(const MachineInstr *MI, unsigned OpNo, Index: llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp diff -c /dev/null llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp:1.10.2.2 *** /dev/null Wed Nov 16 12:32:47 2005 --- llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp Wed Nov 16 12:32:36 2005 *************** *** 0 **** --- 1,556 ---- + //===---- IA64ISelDAGToDAG.cpp - IA64 pattern matching inst selector ------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Duraid Madina and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file defines a pattern matching instruction selector for IA64, + // converting a legalized dag to an IA64 dag. + // + //===----------------------------------------------------------------------===// + + #include "IA64.h" + #include "IA64TargetMachine.h" + #include "IA64ISelLowering.h" + #include "llvm/CodeGen/MachineInstrBuilder.h" + #include "llvm/CodeGen/MachineFunction.h" + #include "llvm/CodeGen/SSARegMap.h" + #include "llvm/CodeGen/SelectionDAG.h" + #include "llvm/CodeGen/SelectionDAGISel.h" + #include "llvm/Target/TargetOptions.h" + #include "llvm/ADT/Statistic.h" + #include "llvm/Constants.h" + #include "llvm/GlobalValue.h" + #include "llvm/Support/Debug.h" + #include "llvm/Support/MathExtras.h" + using namespace llvm; + + namespace { + Statistic<> FusedFP ("ia64-codegen", "Number of fused fp operations"); + Statistic<> FrameOff("ia64-codegen", "Number of frame idx offsets collapsed"); + + //===--------------------------------------------------------------------===// + /// IA64DAGToDAGISel - IA64 specific code to select IA64 machine + /// instructions for SelectionDAG operations. + /// + class IA64DAGToDAGISel : public SelectionDAGISel { + IA64TargetLowering IA64Lowering; + unsigned GlobalBaseReg; + public: + IA64DAGToDAGISel(TargetMachine &TM) + : SelectionDAGISel(IA64Lowering), IA64Lowering(TM) {} + + virtual bool runOnFunction(Function &Fn) { + // Make sure we re-emit a set of the global base reg if necessary + GlobalBaseReg = 0; + return SelectionDAGISel::runOnFunction(Fn); + } + + /// getI64Imm - Return a target constant with the specified value, of type + /// i64. + inline SDOperand getI64Imm(uint64_t Imm) { + return CurDAG->getTargetConstant(Imm, MVT::i64); + } + + /// getGlobalBaseReg - insert code into the entry mbb to materialize the PIC + /// base register. Return the virtual register that holds this value. + // SDOperand getGlobalBaseReg(); TODO: hmm + + // Select - Convert the specified operand from a target-independent to a + // target-specific node if it hasn't already been changed. + SDOperand Select(SDOperand Op); + + SDNode *SelectIntImmediateExpr(SDOperand LHS, SDOperand RHS, + unsigned OCHi, unsigned OCLo, + bool IsArithmetic = false, + bool Negate = false); + SDNode *SelectBitfieldInsert(SDNode *N); + + /// SelectCC - Select a comparison of the specified values with the + /// specified condition code, returning the CR# of the expression. + SDOperand SelectCC(SDOperand LHS, SDOperand RHS, ISD::CondCode CC); + + /// SelectAddr - Given the specified address, return the two operands for a + /// load/store instruction, and return true if it should be an indexed [r+r] + /// operation. + bool SelectAddr(SDOperand Addr, SDOperand &Op1, SDOperand &Op2); + + SDOperand BuildSDIVSequence(SDNode *N); + SDOperand BuildUDIVSequence(SDNode *N); + + /// InstructionSelectBasicBlock - This callback is invoked by + /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. + virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); + + virtual const char *getPassName() const { + return "IA64 (Itanium) DAG->DAG Instruction Selector"; + } + + // Include the pieces autogenerated from the target description. + #include "IA64GenDAGISel.inc" + + private: + SDOperand SelectCALL(SDOperand Op); + }; + } + + /// InstructionSelectBasicBlock - This callback is invoked by + /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. + void IA64DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { + DEBUG(BB->dump()); + + // The selection process is inherently a bottom-up recursive process (users + // select their uses before themselves). Given infinite stack space, we + // could just start selecting on the root and traverse the whole graph. In + // practice however, this causes us to run out of stack space on large basic + // blocks. To avoid this problem, select the entry node, then all its uses, + // iteratively instead of recursively. + std::vector Worklist; + Worklist.push_back(DAG.getEntryNode()); + + // Note that we can do this in the IA64 target (scanning forward across token + // chain edges) because no nodes ever get folded across these edges. On a + // target like X86 which supports load/modify/store operations, this would + // have to be more careful. + while (!Worklist.empty()) { + SDOperand Node = Worklist.back(); + Worklist.pop_back(); + + // Chose from the least deep of the top two nodes. + if (!Worklist.empty() && + Worklist.back().Val->getNodeDepth() < Node.Val->getNodeDepth()) + std::swap(Worklist.back(), Node); + + if ((Node.Val->getOpcode() >= ISD::BUILTIN_OP_END && + Node.Val->getOpcode() < IA64ISD::FIRST_NUMBER) || + CodeGenMap.count(Node)) continue; + + for (SDNode::use_iterator UI = Node.Val->use_begin(), + E = Node.Val->use_end(); UI != E; ++UI) { + // Scan the values. If this use has a value that is a token chain, add it + // to the worklist. + SDNode *User = *UI; + for (unsigned i = 0, e = User->getNumValues(); i != e; ++i) + if (User->getValueType(i) == MVT::Other) { + Worklist.push_back(SDOperand(User, i)); + break; + } + } + + // Finally, legalize this node. + Select(Node); + } + + // Select target instructions for the DAG. + DAG.setRoot(Select(DAG.getRoot())); + CodeGenMap.clear(); + DAG.RemoveDeadNodes(); + + // Emit machine code to BB. + ScheduleAndEmitDAG(DAG); + } + + + SDOperand IA64DAGToDAGISel::SelectCALL(SDOperand Op) { + SDNode *N = Op.Val; + SDOperand Chain = Select(N->getOperand(0)); + + unsigned CallOpcode; + std::vector CallOperands; + + // save the current GP, SP and RP : FIXME: do we need to do all 3 always? + SDOperand GPBeforeCall = CurDAG->getCopyFromReg(Chain, IA64::r1, MVT::i64); + Chain = GPBeforeCall.getValue(1); + SDOperand SPBeforeCall = CurDAG->getCopyFromReg(Chain, IA64::r12, MVT::i64); + Chain = SPBeforeCall.getValue(1); + SDOperand RPBeforeCall = CurDAG->getCopyFromReg(Chain, IA64::rp, MVT::i64); + Chain = RPBeforeCall.getValue(1); + + // if we can call directly, do so + if (GlobalAddressSDNode *GASD = + dyn_cast(N->getOperand(1))) { + CallOpcode = IA64::BRCALL_IPREL; + CallOperands.push_back(CurDAG->getTargetGlobalAddress(GASD->getGlobal(), + MVT::i64)); + } else if (ExternalSymbolSDNode *ESSDN = // FIXME: we currently NEED this + // case for correctness, to avoid + // "non-pic code with imm reloc.n + // against dynamic symbol" errors + dyn_cast(N->getOperand(1))) { + CallOpcode = IA64::BRCALL_IPREL; + CallOperands.push_back(N->getOperand(1)); + } else { + // otherwise we need to load the function descriptor, + // load the branch target (function)'s entry point and GP, + // branch (call) then restore the GP + + SDOperand FnDescriptor = Select(N->getOperand(1)); + + // load the branch target's entry point [mem] and + // GP value [mem+8] + SDOperand targetEntryPoint=CurDAG->getTargetNode(IA64::LD8, MVT::i64, + FnDescriptor); + Chain = targetEntryPoint.getValue(1); + SDOperand targetGPAddr=CurDAG->getTargetNode(IA64::ADDS, MVT::i64, + FnDescriptor, CurDAG->getConstant(8, MVT::i64)); + Chain = targetGPAddr.getValue(1); + SDOperand targetGP=CurDAG->getTargetNode(IA64::LD8, MVT::i64, + targetGPAddr); + Chain = targetGP.getValue(1); + + /* FIXME? (methcall still fails) + SDOperand targetEntryPoint=CurDAG->getLoad(MVT::i64, Chain, FnDescriptor, + CurDAG->getSrcValue(0)); + SDOperand targetGPAddr=CurDAG->getNode(ISD::ADD, MVT::i64, FnDescriptor, + CurDAG->getConstant(8, MVT::i64)); + SDOperand targetGP=CurDAG->getLoad(MVT::i64, Chain, targetGPAddr, + CurDAG->getSrcValue(0)); + */ + + /* this is just the long way of writing the two lines below? + // Copy the callee GP into r1 + SDOperand r1 = CurDAG->getRegister(IA64::r1, MVT::i64); + Chain = CurDAG->getNode(ISD::CopyToReg, MVT::i64, Chain, r1, + targetGP); + + + // Copy the callee address into the b6 branch register + SDOperand B6 = CurDAG->getRegister(IA64::B6, MVT::i64); + Chain = CurDAG->getNode(ISD::CopyToReg, MVT::i64, Chain, B6, + targetEntryPoint); + */ + + Chain = CurDAG->getCopyToReg(Chain, IA64::r1, targetGP); + Chain = CurDAG->getCopyToReg(Chain, IA64::B6, targetEntryPoint); + + CallOperands.push_back(CurDAG->getRegister(IA64::B6, MVT::i64)); + CallOpcode = IA64::BRCALL_INDIRECT; + } + + // see section 8.5.8 of "Itanium Software Conventions and + // Runtime Architecture Guide to see some examples of what's going + // on here. (in short: int args get mapped 1:1 'slot-wise' to out0->out7, + // while FP args get mapped to F8->F15 as needed) + + // TODO: support in-memory arguments + + unsigned used_FPArgs=0; // how many FP args have been used so far? + + unsigned intArgs[] = {IA64::out0, IA64::out1, IA64::out2, IA64::out3, + IA64::out4, IA64::out5, IA64::out6, IA64::out7 }; + unsigned FPArgs[] = {IA64::F8, IA64::F9, IA64::F10, IA64::F11, + IA64::F12, IA64::F13, IA64::F14, IA64::F15 }; + + SDOperand InFlag; // Null incoming flag value. + + for (unsigned i = 2, e = N->getNumOperands(); i != e; ++i) { + unsigned DestReg = 0; + MVT::ValueType RegTy = N->getOperand(i).getValueType(); + if (RegTy == MVT::i64) { + assert((i-2) < 8 && "Too many int args"); + DestReg = intArgs[i-2]; + } else { + assert(MVT::isFloatingPoint(N->getOperand(i).getValueType()) && + "Unpromoted integer arg?"); + assert(used_FPArgs < 8 && "Too many fp args"); + DestReg = FPArgs[used_FPArgs++]; + } + + if (N->getOperand(i).getOpcode() != ISD::UNDEF) { + SDOperand Val = Select(N->getOperand(i)); + if(MVT::isInteger(N->getOperand(i).getValueType())) { + Chain = CurDAG->getCopyToReg(Chain, DestReg, Val, InFlag); + InFlag = Chain.getValue(1); + CallOperands.push_back(CurDAG->getRegister(DestReg, RegTy)); + } + // some functions (e.g. printf) want floating point arguments + // *also* passed as in-memory representations in integer registers + // this is FORTRAN legacy junk which we don't _always_ need + // to do, but to be on the safe side, we do. + else if(MVT::isFloatingPoint(N->getOperand(i).getValueType())) { + assert((i-2) < 8 && "FP args alone would fit, but no int regs left"); + // first copy into the appropriate FP reg + Chain = CurDAG->getCopyToReg(Chain, DestReg, Val); + // then copy into the appropriate integer reg + DestReg = intArgs[i-2]; + // GETFD takes an FP reg and writes a GP reg + Chain = CurDAG->getTargetNode(IA64::GETFD, MVT::i64, Val); + // FIXME: this next line is a bit unfortunate + Chain = CurDAG->getCopyToReg(Chain, DestReg, Chain, InFlag); + InFlag = Chain.getValue(1); + CallOperands.push_back(CurDAG->getRegister(DestReg, MVT::i64)); + } + } + } + + // Finally, once everything is in registers to pass to the call, emit the + // call itself. + if (InFlag.Val) + CallOperands.push_back(InFlag); // Strong dep on register copies. + else + CallOperands.push_back(Chain); // Weak dep on whatever occurs before + Chain = CurDAG->getTargetNode(CallOpcode, MVT::Other, MVT::Flag, + CallOperands); + + std::vector CallResults; + + // If the call has results, copy the values out of the ret val registers. + switch (N->getValueType(0)) { + default: assert(0 && "Unexpected ret value!"); + case MVT::Other: break; + case MVT::i1: { + // bools are returned as bytes 0/1 in r8 + SDOperand byteval = CurDAG->getCopyFromReg(Chain, IA64::r8, MVT::i64, + Chain.getValue(1)); + Chain = byteval.getValue(1); + Chain = CurDAG->getTargetNode(IA64::CMPNE, MVT::i1, MVT::Other, + byteval, CurDAG->getRegister(IA64::r0, MVT::i64)).getValue(1); + CallResults.push_back(Chain.getValue(0)); + break; + } + case MVT::i64: + Chain = CurDAG->getCopyFromReg(Chain, IA64::r8, MVT::i64, + Chain.getValue(1)).getValue(1); + CallResults.push_back(Chain.getValue(0)); + break; + case MVT::f64: + Chain = CurDAG->getCopyFromReg(Chain, IA64::F8, N->getValueType(0), + Chain.getValue(1)).getValue(1); + CallResults.push_back(Chain.getValue(0)); + break; + } + + // restore GP, SP and RP - FIXME: this doesn't quite work (e.g. + // methcall / objinst both segfault on exit) and it *really* + // doesn't work unless you have -sched=none + Chain = CurDAG->getCopyToReg(Chain, IA64::r1, GPBeforeCall); + Chain = CurDAG->getCopyToReg(Chain, IA64::r12, SPBeforeCall); + Chain = CurDAG->getCopyToReg(Chain, IA64::rp, RPBeforeCall); + CallResults.push_back(Chain); // llc segfaults w/o this, + // ary3(e.g.) SIGILLs with 3 + + for (unsigned i = 0, e = CallResults.size(); i != e; ++i) + CodeGenMap[Op.getValue(i)] = CallResults[i]; + + return CallResults[Op.ResNo]; + } + + // Select - Convert the specified operand from a target-independent to a + // target-specific node if it hasn't already been changed. + SDOperand IA64DAGToDAGISel::Select(SDOperand Op) { + SDNode *N = Op.Val; + if (N->getOpcode() >= ISD::BUILTIN_OP_END && + N->getOpcode() < IA64ISD::FIRST_NUMBER) + return Op; // Already selected. + + // If this has already been converted, use it. + std::map::iterator CGMI = CodeGenMap.find(Op); + if (CGMI != CodeGenMap.end()) return CGMI->second; + + switch (N->getOpcode()) { + default: break; + + case ISD::CALL: + case ISD::TAILCALL: return SelectCALL(Op); + + /* todo: + * case ISD::DYNAMIC_STACKALLOC: + */ + case ISD::ConstantFP: { + SDOperand Chain = CurDAG->getEntryNode(); // this is a constant, so.. + + if (cast(N)->isExactlyValue(+0.0)) + return CurDAG->getCopyFromReg(Chain, IA64::F0, MVT::f64); + else if (cast(N)->isExactlyValue(+1.0)) + return CurDAG->getCopyFromReg(Chain, IA64::F1, MVT::f64); + else + assert(0 && "Unexpected FP constant!"); + } + + case ISD::FrameIndex: { // TODO: reduce creepyness + int FI = cast(N)->getIndex(); + if (N->hasOneUse()) { + CurDAG->SelectNodeTo(N, IA64::MOV, MVT::i64, + CurDAG->getTargetFrameIndex(FI, MVT::i64)); + return SDOperand(N, 0); + } + return CurDAG->getTargetNode(IA64::MOV, MVT::i64, + CurDAG->getTargetFrameIndex(FI, MVT::i64)); + } + + case ISD::ConstantPool: { + Constant *C = cast(N)->get(); + SDOperand CPI = CurDAG->getTargetConstantPool(C, MVT::i64); + return CurDAG->getTargetNode(IA64::ADDL_GA, MVT::i64, // ? + CurDAG->getRegister(IA64::r1, MVT::i64), CPI); + } + + case ISD::GlobalAddress: { + GlobalValue *GV = cast(N)->getGlobal(); + SDOperand GA = CurDAG->getTargetGlobalAddress(GV, MVT::i64); + SDOperand Tmp = CurDAG->getTargetNode(IA64::ADDL_GA, MVT::i64, + CurDAG->getRegister(IA64::r1, MVT::i64), GA); + return CurDAG->getTargetNode(IA64::LD8, MVT::i64, Tmp); + } + + case ISD::LOAD: + case ISD::EXTLOAD: + case ISD::ZEXTLOAD: { + SDOperand Chain = Select(N->getOperand(0)); + SDOperand Address = Select(N->getOperand(1)); + + MVT::ValueType TypeBeingLoaded = (N->getOpcode() == ISD::LOAD) ? + N->getValueType(0) : cast(N->getOperand(3))->getVT(); + unsigned Opc; + switch (TypeBeingLoaded) { + default: N->dump(); assert(0 && "Cannot load this type!"); + case MVT::i1: { // this is a bool + Opc = IA64::LD1; // first we load a byte, then compare for != 0 + CurDAG->SelectNodeTo(N, IA64::CMPNE, MVT::i1, MVT::Other, + CurDAG->getTargetNode(Opc, MVT::i64, Address), + CurDAG->getRegister(IA64::r0, MVT::i64), Chain); + return SDOperand(N, Op.ResNo); // XXX: early exit + } + case MVT::i8: Opc = IA64::LD1; break; + case MVT::i16: Opc = IA64::LD2; break; + case MVT::i32: Opc = IA64::LD4; break; + case MVT::i64: Opc = IA64::LD8; break; + + case MVT::f32: Opc = IA64::LDF4; break; + case MVT::f64: Opc = IA64::LDF8; break; + } + + CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other, + Address, Chain); // TODO: comment this + + return SDOperand(N, Op.ResNo); + } + + case ISD::TRUNCSTORE: + case ISD::STORE: { + SDOperand Address = Select(N->getOperand(2)); + SDOperand Chain = Select(N->getOperand(0)); + + unsigned Opc; + if (N->getOpcode() == ISD::STORE) { + switch (N->getOperand(1).getValueType()) { + default: assert(0 && "unknown type in store"); + case MVT::i1: { // this is a bool + Opc = IA64::ST1; // we store either 0 or 1 as a byte + CurDAG->SelectNodeTo(N, Opc, MVT::Other, Address, + CurDAG->getTargetNode(IA64::PADDS, MVT::i64, + CurDAG->getRegister(IA64::r0, MVT::i64), + CurDAG->getConstant(1, MVT::i64), + Select(N->getOperand(1))), + Chain); + return SDOperand(N, 0); // XXX: early exit + } + case MVT::i64: Opc = IA64::ST8; break; + case MVT::f64: Opc = IA64::STF8; break; + } + } else { //ISD::TRUNCSTORE + switch(cast(N->getOperand(4))->getVT()) { + default: assert(0 && "unknown type in truncstore"); + case MVT::i8: Opc = IA64::ST1; break; + case MVT::i16: Opc = IA64::ST2; break; + case MVT::i32: Opc = IA64::ST4; break; + case MVT::f32: Opc = IA64::STF4; break; + } + } + + CurDAG->SelectNodeTo(N, Opc, MVT::Other, Select(N->getOperand(2)), + Select(N->getOperand(1)), Chain); + return SDOperand(N, 0); + } + + case ISD::BRCOND: { + SDOperand Chain = Select(N->getOperand(0)); + SDOperand CC = Select(N->getOperand(1)); + MachineBasicBlock *Dest = + cast(N->getOperand(2))->getBasicBlock(); + //FIXME - we do NOT need long branches all the time + CurDAG->SelectNodeTo(N, IA64::BRLCOND_NOTCALL, MVT::Other, CC, CurDAG->getBasicBlock(Dest), Chain); + return SDOperand(N, 0); + } + + case ISD::CALLSEQ_START: + case ISD::CALLSEQ_END: { + int64_t Amt = cast(N->getOperand(1))->getValue(); + unsigned Opc = N->getOpcode() == ISD::CALLSEQ_START ? + IA64::ADJUSTCALLSTACKDOWN : IA64::ADJUSTCALLSTACKUP; + CurDAG->SelectNodeTo(N, Opc, MVT::Other, + getI64Imm(Amt), Select(N->getOperand(0))); + return SDOperand(N, 0); + } + + case ISD::RET: { + SDOperand Chain = Select(N->getOperand(0)); // Token chain. + + switch (N->getNumOperands()) { + default: + assert(0 && "Unknown return instruction!"); + case 2: { + SDOperand RetVal = Select(N->getOperand(1)); + switch (RetVal.getValueType()) { + default: assert(0 && "I don't know how to return this type! (promote?)"); + // FIXME: do I need to add support for bools here? + // (return '0' or '1' in r8, basically...) + // + // FIXME: need to round floats - 80 bits is bad, the tester + // told me so + case MVT::i64: + // we mark r8 as live on exit up above in LowerArguments() + // BuildMI(BB, IA64::MOV, 1, IA64::r8).addReg(Tmp1); + Chain = CurDAG->getCopyToReg(Chain, IA64::r8, RetVal); + break; + case MVT::f64: + // we mark F8 as live on exit up above in LowerArguments() + // BuildMI(BB, IA64::FMOV, 1, IA64::F8).addReg(Tmp1); + Chain = CurDAG->getCopyToReg(Chain, IA64::F8, RetVal); + break; + } + break; + } + case 1: + break; + } + + // we need to copy VirtGPR (the vreg (to become a real reg)) that holds + // the output of this function's alloc instruction back into ar.pfs + // before we return. this copy must not float up above the last + // outgoing call in this function!!! + SDOperand AR_PFSVal = CurDAG->getCopyFromReg(Chain, IA64Lowering.VirtGPR, + MVT::i64); + Chain = AR_PFSVal.getValue(1); + Chain = CurDAG->getCopyToReg(Chain, IA64::AR_PFS, AR_PFSVal); + + CurDAG->SelectNodeTo(N, IA64::RET, MVT::Other, Chain); // and then just emit a 'ret' instruction + + // before returning, restore the ar.pfs register (set by the 'alloc' up top) + // BuildMI(BB, IA64::MOV, 1).addReg(IA64::AR_PFS).addReg(IA64Lowering.VirtGPR); + // + return SDOperand(N, 0); + } + + case ISD::BR: + // FIXME: we don't need long branches all the time! + CurDAG->SelectNodeTo(N, IA64::BRL_NOTCALL, MVT::Other, N->getOperand(1), + Select(N->getOperand(0))); + return SDOperand(N, 0); + + } + + return SelectCode(Op); + } + + + /// createIA64DAGToDAGInstructionSelector - This pass converts a legalized DAG + /// into an IA64-specific DAG, ready for instruction scheduling. + /// + FunctionPass *llvm::createIA64DAGToDAGInstructionSelector(TargetMachine &TM) { + return new IA64DAGToDAGISel(TM); + } + Index: llvm/lib/Target/IA64/IA64ISelLowering.cpp diff -c /dev/null llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.3.2.2 *** /dev/null Wed Nov 16 12:32:47 2005 --- llvm/lib/Target/IA64/IA64ISelLowering.cpp Wed Nov 16 12:32:36 2005 *************** *** 0 **** --- 1,367 ---- + //===-- IA64ISelLowering.cpp - IA64 DAG Lowering Implementation -----------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Duraid Madina and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file implements the IA64ISelLowering class. + // + //===----------------------------------------------------------------------===// + + #include "IA64ISelLowering.h" + #include "IA64MachineFunctionInfo.h" + #include "IA64TargetMachine.h" + #include "llvm/CodeGen/MachineFrameInfo.h" + #include "llvm/CodeGen/MachineFunction.h" + #include "llvm/CodeGen/MachineInstrBuilder.h" + #include "llvm/CodeGen/SelectionDAG.h" + #include "llvm/CodeGen/SSARegMap.h" + #include "llvm/Constants.h" + #include "llvm/Function.h" + using namespace llvm; + + IA64TargetLowering::IA64TargetLowering(TargetMachine &TM) + : TargetLowering(TM) { + + // register class for general registers + addRegisterClass(MVT::i64, IA64::GRRegisterClass); + + // register class for FP registers + addRegisterClass(MVT::f64, IA64::FPRegisterClass); + + // register class for predicate registers + addRegisterClass(MVT::i1, IA64::PRRegisterClass); + + setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand); + setOperationAction(ISD::BRTWOWAY_CC , MVT::Other, Expand); + setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand); + + setSetCCResultType(MVT::i1); + setShiftAmountType(MVT::i64); + + setOperationAction(ISD::EXTLOAD , MVT::i1 , Promote); + + setOperationAction(ISD::ZEXTLOAD , MVT::i1 , Expand); + + setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand); + setOperationAction(ISD::SEXTLOAD , MVT::i8 , Expand); + setOperationAction(ISD::SEXTLOAD , MVT::i16 , Expand); + setOperationAction(ISD::SEXTLOAD , MVT::i32 , Expand); + + setOperationAction(ISD::FREM , MVT::f32 , Expand); + setOperationAction(ISD::FREM , MVT::f64 , Expand); + + setOperationAction(ISD::UREM , MVT::f32 , Expand); + setOperationAction(ISD::UREM , MVT::f64 , Expand); + + setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); + setOperationAction(ISD::MEMSET , MVT::Other, Expand); + setOperationAction(ISD::MEMCPY , MVT::Other, Expand); + + setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote); + setOperationAction(ISD::UINT_TO_FP , MVT::i1 , Promote); + + // We don't support sin/cos/sqrt + setOperationAction(ISD::FSIN , MVT::f64, Expand); + setOperationAction(ISD::FCOS , MVT::f64, Expand); + setOperationAction(ISD::FSQRT, MVT::f64, Expand); + setOperationAction(ISD::FSIN , MVT::f32, Expand); + setOperationAction(ISD::FCOS , MVT::f32, Expand); + setOperationAction(ISD::FSQRT, MVT::f32, Expand); + + //IA64 has these, but they are not implemented + setOperationAction(ISD::CTTZ , MVT::i64 , Expand); + setOperationAction(ISD::CTLZ , MVT::i64 , Expand); + + computeRegisterProperties(); + + addLegalFPImmediate(+0.0); + addLegalFPImmediate(+1.0); + } + + /// isFloatingPointZero - Return true if this is 0.0 or -0.0. + static bool isFloatingPointZero(SDOperand Op) { + if (ConstantFPSDNode *CFP = dyn_cast(Op)) + return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0); + else if (Op.getOpcode() == ISD::EXTLOAD || Op.getOpcode() == ISD::LOAD) { + // Maybe this has already been legalized into the constant pool? + if (ConstantPoolSDNode *CP = dyn_cast(Op.getOperand(1))) + if (ConstantFP *CFP = dyn_cast(CP->get())) + return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0); + } + return false; + } + + std::vector + IA64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { + std::vector ArgValues; + // + // add beautiful description of IA64 stack frame format + // here (from intel 24535803.pdf most likely) + // + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + + GP = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)); + SP = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)); + RP = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)); + + MachineBasicBlock& BB = MF.front(); + + unsigned args_int[] = {IA64::r32, IA64::r33, IA64::r34, IA64::r35, + IA64::r36, IA64::r37, IA64::r38, IA64::r39}; + + unsigned args_FP[] = {IA64::F8, IA64::F9, IA64::F10, IA64::F11, + IA64::F12,IA64::F13,IA64::F14, IA64::F15}; + + unsigned argVreg[8]; + unsigned argPreg[8]; + unsigned argOpc[8]; + + unsigned used_FPArgs = 0; // how many FP args have been used so far? + + unsigned ArgOffset = 0; + int count = 0; + + for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) + { + SDOperand newroot, argt; + if(count < 8) { // need to fix this logic? maybe. + + switch (getValueType(I->getType())) { + default: + assert(0 && "ERROR in LowerArgs: can't lower this type of arg.\n"); + case MVT::f32: + // fixme? (well, will need to for weird FP structy stuff, + // see intel ABI docs) + case MVT::f64: + //XXX BuildMI(&BB, IA64::IDEF, 0, args_FP[used_FPArgs]); + MF.addLiveIn(args_FP[used_FPArgs]); // mark this reg as liveIn + // floating point args go into f8..f15 as-needed, the increment + argVreg[count] = // is below..: + MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::f64)); + // FP args go into f8..f15 as needed: (hence the ++) + argPreg[count] = args_FP[used_FPArgs++]; + argOpc[count] = IA64::FMOV; + argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), argVreg[count], + MVT::f64); + if (I->getType() == Type::FloatTy) + argt = DAG.getNode(ISD::FP_ROUND, MVT::f32, argt); + break; + case MVT::i1: // NOTE: as far as C abi stuff goes, + // bools are just boring old ints + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::i64: + //XXX BuildMI(&BB, IA64::IDEF, 0, args_int[count]); + MF.addLiveIn(args_int[count]); // mark this register as liveIn + argVreg[count] = + MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)); + argPreg[count] = args_int[count]; + argOpc[count] = IA64::MOV; + argt = newroot = + DAG.getCopyFromReg(DAG.getRoot(), argVreg[count], MVT::i64); + if ( getValueType(I->getType()) != MVT::i64) + argt = DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), + newroot); + break; + } + } else { // more than 8 args go into the frame + // Create the frame index object for this incoming parameter... + ArgOffset = 16 + 8 * (count - 8); + int FI = MFI->CreateFixedObject(8, ArgOffset); + + // Create the SelectionDAG nodes corresponding to a load + //from this parameter + SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64); + argt = newroot = DAG.getLoad(getValueType(I->getType()), + DAG.getEntryNode(), FIN, DAG.getSrcValue(NULL)); + } + ++count; + DAG.setRoot(newroot.getValue(1)); + ArgValues.push_back(argt); + } + + + // Create a vreg to hold the output of (what will become) + // the "alloc" instruction + VirtGPR = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)); + BuildMI(&BB, IA64::PSEUDO_ALLOC, 0, VirtGPR); + // we create a PSEUDO_ALLOC (pseudo)instruction for now + /* + BuildMI(&BB, IA64::IDEF, 0, IA64::r1); + + // hmm: + BuildMI(&BB, IA64::IDEF, 0, IA64::r12); + BuildMI(&BB, IA64::IDEF, 0, IA64::rp); + // ..hmm. + + BuildMI(&BB, IA64::MOV, 1, GP).addReg(IA64::r1); + + // hmm: + BuildMI(&BB, IA64::MOV, 1, SP).addReg(IA64::r12); + BuildMI(&BB, IA64::MOV, 1, RP).addReg(IA64::rp); + // ..hmm. + */ + + unsigned tempOffset=0; + + // if this is a varargs function, we simply lower llvm.va_start by + // pointing to the first entry + if(F.isVarArg()) { + tempOffset=0; + VarArgsFrameIndex = MFI->CreateFixedObject(8, tempOffset); + } + + // here we actually do the moving of args, and store them to the stack + // too if this is a varargs function: + for (int i = 0; i < count && i < 8; ++i) { + BuildMI(&BB, argOpc[i], 1, argVreg[i]).addReg(argPreg[i]); + if(F.isVarArg()) { + // if this is a varargs function, we copy the input registers to the stack + int FI = MFI->CreateFixedObject(8, tempOffset); + tempOffset+=8; //XXX: is it safe to use r22 like this? + BuildMI(&BB, IA64::MOV, 1, IA64::r22).addFrameIndex(FI); + // FIXME: we should use st8.spill here, one day + BuildMI(&BB, IA64::ST8, 1, IA64::r22).addReg(argPreg[i]); + } + } + + // Finally, inform the code generator which regs we return values in. + // (see the ISD::RET: case in the instruction selector) + switch (getValueType(F.getReturnType())) { + default: assert(0 && "i have no idea where to return this type!"); + case MVT::isVoid: break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::i64: + MF.addLiveOut(IA64::r8); + break; + case MVT::f32: + case MVT::f64: + MF.addLiveOut(IA64::F8); + break; + } + + return ArgValues; + } + + std::pair + IA64TargetLowering::LowerCallTo(SDOperand Chain, + const Type *RetTy, bool isVarArg, + unsigned CallingConv, bool isTailCall, + SDOperand Callee, ArgListTy &Args, + SelectionDAG &DAG) { + + MachineFunction &MF = DAG.getMachineFunction(); + + unsigned NumBytes = 16; + unsigned outRegsUsed = 0; + + if (Args.size() > 8) { + NumBytes += (Args.size() - 8) * 8; + outRegsUsed = 8; + } else { + outRegsUsed = Args.size(); + } + + // FIXME? this WILL fail if we ever try to pass around an arg that + // consumes more than a single output slot (a 'real' double, int128 + // some sort of aggregate etc.), as we'll underestimate how many 'outX' + // registers we use. Hopefully, the assembler will notice. + MF.getInfo()->outRegsUsed= + std::max(outRegsUsed, MF.getInfo()->outRegsUsed); + + Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, + DAG.getConstant(NumBytes, getPointerTy())); + + std::vector args_to_use; + for (unsigned i = 0, e = Args.size(); i != e; ++i) + { + switch (getValueType(Args[i].second)) { + default: assert(0 && "unexpected argument type!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + //promote to 64-bits, sign/zero extending based on type + //of the argument + if(Args[i].second->isSigned()) + Args[i].first = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, + Args[i].first); + else + Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, + Args[i].first); + break; + case MVT::f32: + //promote to 64-bits + Args[i].first = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Args[i].first); + case MVT::f64: + case MVT::i64: + break; + } + args_to_use.push_back(Args[i].first); + } + + std::vector RetVals; + MVT::ValueType RetTyVT = getValueType(RetTy); + if (RetTyVT != MVT::isVoid) + RetVals.push_back(RetTyVT); + RetVals.push_back(MVT::Other); + + SDOperand TheCall = SDOperand(DAG.getCall(RetVals, Chain, + Callee, args_to_use), 0); + Chain = TheCall.getValue(RetTyVT != MVT::isVoid); + Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, + DAG.getConstant(NumBytes, getPointerTy())); + return std::make_pair(TheCall, Chain); + } + + SDOperand + IA64TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG) { + // vastart just stores the address of the VarArgsFrameIndex slot. + SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64); + return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, + VAListP, DAG.getSrcValue(VAListV)); + } + + std::pair IA64TargetLowering:: + LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG) { + + MVT::ValueType ArgVT = getValueType(ArgTy); + SDOperand Val = DAG.getLoad(MVT::i64, Chain, + VAListP, DAG.getSrcValue(VAListV)); + SDOperand Result = DAG.getLoad(ArgVT, DAG.getEntryNode(), Val, + DAG.getSrcValue(NULL)); + unsigned Amt; + if (ArgVT == MVT::i32 || ArgVT == MVT::f32) + Amt = 8; + else { + assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && + "Other types should have been promoted for varargs!"); + Amt = 8; + } + Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val, + DAG.getConstant(Amt, Val.getValueType())); + Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, + Val, VAListP, DAG.getSrcValue(VAListV)); + return std::make_pair(Result, Chain); + } + + + + std::pair IA64TargetLowering:: + LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, + SelectionDAG &DAG) { + assert(0 && "LowerFrameReturnAddress unimplemented"); + abort(); + } + Index: llvm/lib/Target/IA64/IA64ISelLowering.h diff -c /dev/null llvm/lib/Target/IA64/IA64ISelLowering.h:1.1.4.2 *** /dev/null Wed Nov 16 12:32:47 2005 --- llvm/lib/Target/IA64/IA64ISelLowering.h Wed Nov 16 12:32:36 2005 *************** *** 0 **** --- 1,88 ---- + //===-- IA64ISelLowering.h - IA64 DAG Lowering Interface --------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Duraid Madina and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file defines the interfaces that IA64 uses to lower LLVM code into a + // selection DAG. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_TARGET_IA64_IA64ISELLOWERING_H + #define LLVM_TARGET_IA64_IA64ISELLOWERING_H + + #include "llvm/Target/TargetLowering.h" + #include "llvm/CodeGen/SelectionDAG.h" + #include "IA64.h" + + namespace llvm { + namespace IA64ISD { + enum NodeType { + // Start the numbering where the builting ops and target ops leave off. + FIRST_NUMBER = ISD::BUILTIN_OP_END+IA64::INSTRUCTION_LIST_END, + + /// FSEL - Traditional three-operand fsel node. + /// + FSEL, + + /// FCFID - The FCFID instruction, taking an f64 operand and producing + /// and f64 value containing the FP representation of the integer that + /// was temporarily in the f64 operand. + FCFID, + + /// FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64 + /// operand, producing an f64 value containing the integer representation + /// of that FP value. + FCTIDZ, FCTIWZ, + }; + } + + class IA64TargetLowering : public TargetLowering { + int VarArgsFrameIndex; // FrameIndex for start of varargs area. + //int ReturnAddrIndex; // FrameIndex for return slot. + unsigned GP, SP, RP; // FIXME - clean this mess up + + public: + IA64TargetLowering(TargetMachine &TM); + + unsigned VirtGPR; // this is public so it can be accessed in the selector + // for ISD::RET. add an accessor instead? FIXME + + /// LowerOperation - Provide custom lowering hooks for some operations. + /// + // XXX virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); + + /// LowerArguments - This hook must be implemented to indicate how we should + /// lower the arguments for the specified function, into the specified DAG. + virtual std::vector + LowerArguments(Function &F, SelectionDAG &DAG); + + /// LowerCallTo - This hook lowers an abstract call to a function into an + /// actual call. + virtual std::pair + LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, + unsigned CC, + bool isTailCall, SDOperand Callee, ArgListTy &Args, + SelectionDAG &DAG); + + virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG); + + virtual std::pair + LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG); + + virtual std::pair + LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, + SelectionDAG &DAG); + + // XXX virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI, + // XXX MachineBasicBlock *MBB); + }; + } + + #endif // LLVM_TARGET_IA64_IA64ISELLOWERING_H Index: llvm/lib/Target/IA64/IA64ISelPattern.cpp diff -u llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.66 llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.66.2.1 --- llvm/lib/Target/IA64/IA64ISelPattern.cpp:1.66 Thu Oct 6 23:50:48 2005 +++ llvm/lib/Target/IA64/IA64ISelPattern.cpp Wed Nov 16 12:32:36 2005 @@ -84,7 +84,7 @@ setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote); setOperationAction(ISD::UINT_TO_FP , MVT::i1 , Promote); - + // We don't support sin/cos/sqrt setOperationAction(ISD::FSIN , MVT::f64, Expand); setOperationAction(ISD::FCOS , MVT::f64, Expand); @@ -96,6 +96,9 @@ //IA64 has these, but they are not implemented setOperationAction(ISD::CTTZ , MVT::i64 , Expand); setOperationAction(ISD::CTLZ , MVT::i64 , Expand); + // FIXME: implement mulhs (xma.h) and mulhu (xma.hu) + setOperationAction(ISD::MULHS , MVT::i64 , Expand); + setOperationAction(ISD::MULHU , MVT::i64 , Expand); computeRegisterProperties(); @@ -1463,7 +1466,7 @@ */ BuildMI(BB, IA64::PCMPEQUNC, 3, pTemp1) .addReg(IA64::r0).addReg(IA64::r0).addReg(pA); - BuildMI(BB, IA64::TPCMPEQ, 3, Result) + BuildMI(BB, IA64::TPCMPEQ, 4, Result) .addReg(pTemp1).addReg(IA64::r0).addReg(IA64::r0).addReg(pB); break; } @@ -1954,8 +1957,13 @@ Select(Chain); IA64Lowering.restoreGP(BB); unsigned dummy = MakeReg(MVT::i64); - BuildMI(BB, IA64::ADD, 2, dummy).addConstantPoolIndex(CPIdx) - .addReg(IA64::r1); // CPI+GP + unsigned dummy2 = MakeReg(MVT::i64); + BuildMI(BB, IA64::MOVLIMM64, 1, dummy2).addConstantPoolIndex(CPIdx); + BuildMI(BB, IA64::ADD, 2, dummy).addReg(dummy2).addReg(IA64::r1); //CPI+GP + + + // OLD BuildMI(BB, IA64::ADD, 2, dummy).addConstantPoolIndex(CPIdx) + // (FIXME!) .addReg(IA64::r1); // CPI+GP if(!isBool) BuildMI(BB, Opc, 1, Result).addReg(dummy); else { // emit a little pseudocode to load a bool (stored in one byte) Index: llvm/lib/Target/IA64/IA64InstrFormats.td diff -u llvm/lib/Target/IA64/IA64InstrFormats.td:1.1 llvm/lib/Target/IA64/IA64InstrFormats.td:1.1.4.1 --- llvm/lib/Target/IA64/IA64InstrFormats.td:1.1 Thu Mar 17 12:17:03 2005 +++ llvm/lib/Target/IA64/IA64InstrFormats.td Wed Nov 16 12:32:36 2005 @@ -36,6 +36,14 @@ let Inst{5-0} = qpReg; } +class AForm_DAG opcode, bits<6> qpReg, dag OL, string asmstr, + list pattern> : + InstIA64 { + + let Pattern = pattern; + let Inst{5-0} = qpReg; +} + let isBranch = 1, isTerminator = 1 in class BForm opcode, bits<6> x6, bits<3> btype, dag OL, string asmstr> : InstIA64 { @@ -64,4 +72,8 @@ class PseudoInstIA64 : InstIA64<0, OL, nm> { } +class PseudoInstIA64_DAG pattern> + : InstIA64<0, OL, nm> { + let Pattern = pattern; +} Index: llvm/lib/Target/IA64/IA64InstrInfo.td diff -u llvm/lib/Target/IA64/IA64InstrInfo.td:1.15 llvm/lib/Target/IA64/IA64InstrInfo.td:1.15.2.1 --- llvm/lib/Target/IA64/IA64InstrInfo.td:1.15 Wed Sep 14 16:11:13 2005 +++ llvm/lib/Target/IA64/IA64InstrInfo.td Wed Nov 16 12:32:36 2005 @@ -15,11 +15,12 @@ include "IA64InstrFormats.td" +def u2imm : Operand; def u6imm : Operand; def s8imm : Operand { let PrintMethod = "printS8ImmOperand"; } -def s14imm : Operand { +def s14imm : Operand { let PrintMethod = "printS14ImmOperand"; } def s22imm : Operand { @@ -32,24 +33,363 @@ let PrintMethod = "printS64ImmOperand"; } +let PrintMethod = "printGlobalOperand" in + def globaladdress : Operand; + // the asmprinter needs to know about calls let PrintMethod = "printCallOperand" in def calltarget : Operand; -def PHI : PseudoInstIA64<(ops variable_ops), "PHI">; -def IDEF : PseudoInstIA64<(ops variable_ops), "// IDEF">; -def IUSE : PseudoInstIA64<(ops variable_ops), "// IUSE">; -def ADJUSTCALLSTACKUP : PseudoInstIA64<(ops variable_ops), - "// ADJUSTCALLSTACKUP">; -def ADJUSTCALLSTACKDOWN : PseudoInstIA64<(ops variable_ops), - "// ADJUSTCALLSTACKDOWN">; -def PSEUDO_ALLOC : PseudoInstIA64<(ops GR:$foo), "// PSEUDO_ALLOC">; +/* new daggy action!!! */ -def ALLOC : AForm<0x03, 0x0b, - (ops GR:$dst, i8imm:$inputs, i8imm:$locals, i8imm:$outputs, i8imm:$rotating), - "alloc $dst = ar.pfs,$inputs,$locals,$outputs,$rotating;;">; +def is32ones : PatLeaf<(i64 imm), [{ + // is32ones predicate - True if the immediate is 0x00000000FFFFFFFF + // Used to create ZXT4s appropriately + uint64_t v = (uint64_t)N->getValue(); + return (v == 0x00000000FFFFFFFFLL); +}]>; + +// isMIXable predicates - True if the immediate is +// 0xFF00FF00FF00FF00, 0x00FF00FF00FF00FF +// etc, through 0x00000000FFFFFFFF +// Used to test for the suitability of mix* +def isMIX1Lable: PatLeaf<(i64 imm), [{ + return((uint64_t)N->getValue()==0xFF00FF00FF00FF00LL); +}]>; +def isMIX1Rable: PatLeaf<(i64 imm), [{ + return((uint64_t)N->getValue()==0x00FF00FF00FF00FFLL); +}]>; +def isMIX2Lable: PatLeaf<(i64 imm), [{ + return((uint64_t)N->getValue()==0xFFFF0000FFFF0000LL); +}]>; +def isMIX2Rable: PatLeaf<(i64 imm), [{ + return((uint64_t)N->getValue()==0x0000FFFF0000FFFFLL); +}]>; +def isMIX4Lable: PatLeaf<(i64 imm), [{ + return((uint64_t)N->getValue()==0xFFFFFFFF00000000LL); +}]>; +def isMIX4Rable: PatLeaf<(i64 imm), [{ + return((uint64_t)N->getValue()==0x00000000FFFFFFFFLL); +}]>; + +def isSHLADDimm: PatLeaf<(i64 imm), [{ + // isSHLADDimm predicate - True if the immediate is exactly 1, 2, 3 or 4 + // - 0 is *not* okay. + // Used to create shladd instructions appropriately + int64_t v = (int64_t)N->getValue(); + return (v >= 1 && v <= 4); +}]>; + +def immSExt14 : PatLeaf<(i64 imm), [{ + // immSExt14 predicate - True if the immediate fits in a 14-bit sign extended + // field. Used by instructions like 'adds'. + int64_t v = (int64_t)N->getValue(); + return (v <= 8191 && v >= -8192); +}]>; + +def imm64 : PatLeaf<(i64 imm), [{ + // imm64 predicate - True if the immediate fits in a 64-bit + // field - i.e., true. used to keep movl happy + return true; +}]>; + +def ADD : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), + "add $dst = $src1, $src2;;", + [(set GR:$dst, (add GR:$src1, GR:$src2))]>; + +def ADD1 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), + "add $dst = $src1, $src2, 1;;", + [(set GR:$dst, (add (add GR:$src1, GR:$src2), 1))]>; + +def ADDS : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, s14imm:$imm), + "adds $dst = $imm, $src1;;", + [(set GR:$dst, (add GR:$src1, immSExt14:$imm))]>; + +def PADDS: AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, s14imm:$imm, PR:$qp), + "($qp) adds $dst = $imm, $src1;;", + []>; + +def MOVL : AForm_DAG<0x03, 0x0b, (ops GR:$dst, s64imm:$imm), + "movl $dst = $imm;;", + [(set GR:$dst, imm64:$imm)]>; + +def ADDL_GA : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, globaladdress:$imm), + "addl $dst = $imm, $src1;;", + []>; + +def SUB : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), + "sub $dst = $src1, $src2;;", + [(set GR:$dst, (sub GR:$src1, GR:$src2))]>; + +def SUB1 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), + "sub $dst = $src1, $src2, 1;;", + [(set GR:$dst, (add (sub GR: $src1, GR:$src2), -1))]>; + +let isTwoAddress = 1 in { +def TPCADDIMM22 : AForm<0x03, 0x0b, + (ops GR:$dst, GR:$src1, s22imm:$imm, PR:$qp), + "($qp) add $dst = $imm, $dst;;">; +def TPCMPIMM8NE : AForm<0x03, 0x0b, + (ops PR:$dst, PR:$src1, s22imm:$imm, GR:$src2, PR:$qp), + "($qp) cmp.ne $dst , p0 = $imm, $src2;;">; +} + +// zero extend a bool (predicate reg) into an integer reg +def ZXTb : Pat<(zext PR:$src), + (TPCADDIMM22 (ADDS r0, 0), 1, PR:$src)>; + +// normal sign/zero-extends +def SXT1 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src), "sxt1 $dst = $src;;", + [(set GR:$dst, (sext_inreg GR:$src, i8))]>; +def ZXT1 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src), "zxt1 $dst = $src;;", + [(set GR:$dst, (and GR:$src, 255))]>; +def SXT2 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src), "sxt2 $dst = $src;;", + [(set GR:$dst, (sext_inreg GR:$src, i16))]>; +def ZXT2 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src), "zxt2 $dst = $src;;", + [(set GR:$dst, (and GR:$src, 65535))]>; +def SXT4 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src), "sxt4 $dst = $src;;", + [(set GR:$dst, (sext_inreg GR:$src, i32))]>; +def ZXT4 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src), "zxt4 $dst = $src;;", + [(set GR:$dst, (and GR:$src, is32ones))]>; + +// fixme: shrs vs shru? +def MIX1L : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), + "mix1.l $dst = $src1, $src2;;", + [(set GR:$dst, (or (and GR:$src1, isMIX1Lable), + (and (srl GR:$src2, 8), isMIX1Lable)))]>; + +def MIX2L : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), + "mix2.l $dst = $src1, $src2;;", + [(set GR:$dst, (or (and GR:$src1, isMIX2Lable), + (and (srl GR:$src2, 16), isMIX2Lable)))]>; + +def MIX4L : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), + "mix4.l $dst = $src1, $src2;;", + [(set GR:$dst, (or (and GR:$src1, isMIX4Lable), + (and (srl GR:$src2, 32), isMIX4Lable)))]>; + +def MIX1R : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), + "mix1.r $dst = $src1, $src2;;", + [(set GR:$dst, (or (and (shl GR:$src1, 8), isMIX1Rable), + (and GR:$src2, isMIX1Rable)))]>; + +def MIX2R : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), + "mix2.r $dst = $src1, $src2;;", + [(set GR:$dst, (or (and (shl GR:$src1, 16), isMIX2Rable), + (and GR:$src2, isMIX2Rable)))]>; + +def MIX4R : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), + "mix4.r $dst = $src1, $src2;;", + [(set GR:$dst, (or (and (shl GR:$src1, 32), isMIX4Rable), + (and GR:$src2, isMIX4Rable)))]>; + +def GETFSIGD : AForm_DAG<0x03, 0x0b, (ops GR:$dst, FP:$src), + "getf.sig $dst = $src;;", + []>; + +def SETFSIGD : AForm_DAG<0x03, 0x0b, (ops FP:$dst, GR:$src), + "setf.sig $dst = $src;;", + []>; + +def XMALD : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), + "xma.l $dst = $src1, $src2, $src3;;", + []>; +def XMAHD : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), + "xma.h $dst = $src1, $src2, $src3;;", + []>; +def XMAHUD : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), + "xma.hu $dst = $src1, $src2, $src3;;", + []>; + +// pseudocode for integer multiplication +def : Pat<(mul GR:$src1, GR:$src2), + (GETFSIGD (XMALD (SETFSIGD GR:$src1), (SETFSIGD GR:$src2), F0))>; +def : Pat<(mulhs GR:$src1, GR:$src2), + (GETFSIGD (XMAHD (SETFSIGD GR:$src1), (SETFSIGD GR:$src2), F0))>; +def : Pat<(mulhu GR:$src1, GR:$src2), + (GETFSIGD (XMAHUD (SETFSIGD GR:$src1), (SETFSIGD GR:$src2), F0))>; + +// TODO: addp4 (addp4 dst = src, r0 is a 32-bit add) +// has imm form, too + +// def ADDS : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, s14imm:$imm), +// "adds $dst = $imm, $src1;;">; + +def AND : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), + "and $dst = $src1, $src2;;", + [(set GR:$dst, (and GR:$src1, GR:$src2))]>; +def ANDCM : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), + "andcm $dst = $src1, $src2;;", + [(set GR:$dst, (and GR:$src1, (not GR:$src2)))]>; +// TODO: and/andcm/or/xor/add/sub/shift immediate forms +def OR : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), + "or $dst = $src1, $src2;;", + [(set GR:$dst, (or GR:$src1, GR:$src2))]>; + +def pOR : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2, PR:$qp), + "($qp) or $dst = $src1, $src2;;">; + +// the following are all a bit unfortunate: we throw away the complement +// of the compare! +def CMPEQ : AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), + "cmp.eq $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (seteq GR:$src1, GR:$src2))]>; +def CMPGT : AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), + "cmp.gt $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setgt GR:$src1, GR:$src2))]>; +def CMPGE : AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), + "cmp.ge $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setge GR:$src1, GR:$src2))]>; +def CMPLT : AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), + "cmp.lt $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setlt GR:$src1, GR:$src2))]>; +def CMPLE : AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), + "cmp.le $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setle GR:$src1, GR:$src2))]>; +def CMPNE : AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), + "cmp.ne $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setne GR:$src1, GR:$src2))]>; +def CMPLTU: AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), + "cmp.ltu $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setult GR:$src1, GR:$src2))]>; +def CMPGTU: AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), + "cmp.gtu $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setugt GR:$src1, GR:$src2))]>; +def CMPLEU: AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), + "cmp.leu $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setule GR:$src1, GR:$src2))]>; +def CMPGEU: AForm_DAG<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), + "cmp.geu $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setuge GR:$src1, GR:$src2))]>; + +// and we do the whole thing again for FP compares! +def FCMPEQ : AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), + "fcmp.eq $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (seteq FP:$src1, FP:$src2))]>; +def FCMPGT : AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), + "fcmp.gt $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setgt FP:$src1, FP:$src2))]>; +def FCMPGE : AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), + "fcmp.ge $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setge FP:$src1, FP:$src2))]>; +def FCMPLT : AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), + "fcmp.lt $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setlt FP:$src1, FP:$src2))]>; +def FCMPLE : AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), + "fcmp.le $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setle FP:$src1, FP:$src2))]>; +def FCMPNE : AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), + "fcmp.neq $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setne FP:$src1, FP:$src2))]>; +def FCMPLTU: AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), + "fcmp.ltu $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setult FP:$src1, FP:$src2))]>; +def FCMPGTU: AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), + "fcmp.gtu $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setugt FP:$src1, FP:$src2))]>; +def FCMPLEU: AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), + "fcmp.leu $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setule FP:$src1, FP:$src2))]>; +def FCMPGEU: AForm_DAG<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), + "fcmp.geu $dst, p0 = $src1, $src2;;", + [(set PR:$dst, (setuge FP:$src1, FP:$src2))]>; + +def PCMPEQUNCR0R0 : AForm<0x03, 0x0b, (ops PR:$dst, PR:$qp), + "($qp) cmp.eq.unc $dst, p0 = r0, r0;;">; + +def : Pat<(trunc GR:$src), // truncate i64 to i1 + (CMPNE GR:$src, r0)>; // $src!=0? If so, PR:$dst=true + +let isTwoAddress=1 in { + def TPCMPEQR0R0 : AForm<0x03, 0x0b, (ops PR:$dst, PR:$bogus, PR:$qp), + "($qp) cmp.eq $dst, p0 = r0, r0;;">; + def TPCMPNER0R0 : AForm<0x03, 0x0b, (ops PR:$dst, PR:$bogus, PR:$qp), + "($qp) cmp.ne $dst, p0 = r0, r0;;">; +} + +/* our pseudocode for OR on predicates is: +pC = pA OR pB +------------- +(pA) cmp.eq.unc pC,p0 = r0,r0 // pC = pA + ;; +(pB) cmp.eq pC,p0 = r0,r0 // if (pB) pC = 1 */ + +def bOR : Pat<(or PR:$src1, PR:$src2), + (TPCMPEQR0R0 (PCMPEQUNCR0R0 PR:$src1), PR:$src2)>; + +/* our pseudocode for AND on predicates is: + * +(pA) cmp.eq.unc pC,p0 = r0,r0 // pC = pA + cmp.eq pTemp,p0 = r0,r0 // pTemp = NOT pB + ;; +(pB) cmp.ne pTemp,p0 = r0,r0 + ;; +(pTemp)cmp.ne pC,p0 = r0,r0 // if (NOT pB) pC = 0 */ + +def bAND : Pat<(and PR:$src1, PR:$src2), + ( TPCMPNER0R0 (PCMPEQUNCR0R0 PR:$src1), + (TPCMPNER0R0 (CMPEQ r0, r0), PR:$src2) )>; + +/* one possible routine for XOR on predicates is: + + // Compute px = py ^ pz + // using sum of products: px = (py & !pz) | (pz & !py) + // Uses 5 instructions in 3 cycles. + // cycle 1 +(pz) cmp.eq.unc px = r0, r0 // px = pz +(py) cmp.eq.unc pt = r0, r0 // pt = py + ;; + // cycle 2 +(pt) cmp.ne.and px = r0, r0 // px = px & !pt (px = pz & !pt) +(pz) cmp.ne.and pt = r0, r0 // pt = pt & !pz + ;; + } { .mmi + // cycle 3 +(pt) cmp.eq.or px = r0, r0 // px = px | pt + +*** Another, which we use here, requires one scratch GR. it is: + + mov rt = 0 // initialize rt off critical path + ;; + + // cycle 1 +(pz) cmp.eq.unc px = r0, r0 // px = pz +(pz) mov rt = 1 // rt = pz + ;; + // cycle 2 +(py) cmp.ne px = 1, rt // if (py) px = !pz + +.. these routines kindly provided by Jim Hull +*/ + +def bXOR : Pat<(xor PR:$src1, PR:$src2), + (TPCMPIMM8NE (PCMPEQUNCR0R0 PR:$src2), 1, + (PADDS r0, 1, PR:$src2), + PR:$src1)>; + +def XOR : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), + "xor $dst = $src1, $src2;;", + [(set GR:$dst, (xor GR:$src1, GR:$src2))]>; + +def SHLADD: AForm_DAG<0x03, 0x0b, (ops GR:$dst,GR:$src1,s64imm:$imm,GR:$src2), + "shladd $dst = $src1, $imm, $src2;;", + [(set GR:$dst, (add GR:$src2, (shl GR:$src1, isSHLADDimm:$imm)))]>; + +def SHL : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), + "shl $dst = $src1, $src2;;", + [(set GR:$dst, (shl GR:$src1, GR:$src2))]>; + +def SHRU : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), + "shr.u $dst = $src1, $src2;;", + [(set GR:$dst, (srl GR:$src1, GR:$src2))]>; + +def SHRS : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), + "shr $dst = $src1, $src2;;", + [(set GR:$dst, (sra GR:$src1, GR:$src2))]>; def MOV : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src), "mov $dst = $src;;">; +def FMOV : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), + "mov $dst = $src;;">; // XXX: there _is_ no fmov def PMOV : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src, PR:$qp), "($qp) mov $dst = $src;;">; @@ -71,6 +411,43 @@ "($qp) mov $dst = $src;;">; } +// TODO: select bools +def SELECTINT : Pat<(select PR:$which, GR:$src1, GR:$src2), + (CMOV (MOV GR:$src2), GR:$src1, PR:$which)>; // note order! +def SELECTFP : Pat<(select PR:$which, FP:$src1, FP:$src2), + (CFMOV (FMOV FP:$src2), FP:$src1, PR:$which)>; // note order! + +// load constants of various sizes // FIXME: prettyprint -ve constants +def : Pat<(i64 immSExt14:$imm), (ADDS r0, immSExt14:$imm)>; +def : Pat<(i64 imm64:$imm), (MOVL imm64:$imm)>; +def : Pat<(i1 -1), (CMPEQ r0, r0)>; // TODO: this should just be a ref to p0 +def : Pat<(i1 0), (CMPNE r0, r0)>; // TODO: any instruction actually *using* + // this predicate should be killed! + +// TODO: support postincrement (reg, imm9) loads+stores - this needs more +// tablegen support + +def PHI : PseudoInstIA64<(ops variable_ops), "PHI">; +def IDEF : PseudoInstIA64<(ops variable_ops), "// IDEF">; + +def IDEF_GR_D : PseudoInstIA64_DAG<(ops GR:$reg), "// $reg = IDEF", + [(set GR:$reg, (undef))]>; +def IDEF_FP_D : PseudoInstIA64_DAG<(ops FP:$reg), "// $reg = IDEF", + [(set FP:$reg, (undef))]>; +def IDEF_PR_D : PseudoInstIA64_DAG<(ops PR:$reg), "// $reg = IDEF", + [(set PR:$reg, (undef))]>; + +def IUSE : PseudoInstIA64<(ops variable_ops), "// IUSE">; +def ADJUSTCALLSTACKUP : PseudoInstIA64<(ops variable_ops), + "// ADJUSTCALLSTACKUP">; +def ADJUSTCALLSTACKDOWN : PseudoInstIA64<(ops variable_ops), + "// ADJUSTCALLSTACKDOWN">; +def PSEUDO_ALLOC : PseudoInstIA64<(ops GR:$foo), "// PSEUDO_ALLOC">; + +def ALLOC : AForm<0x03, 0x0b, + (ops GR:$dst, i8imm:$inputs, i8imm:$locals, i8imm:$outputs, i8imm:$rotating), + "alloc $dst = ar.pfs,$inputs,$locals,$outputs,$rotating;;">; + let isTwoAddress = 1 in { def TCMPNE : AForm<0x03, 0x0b, (ops PR:$dst, PR:$src2, GR:$src3, GR:$src4), @@ -96,85 +473,18 @@ def MOVLIMM64 : AForm<0x03, 0x0b, (ops GR:$dst, s64imm:$imm), "movl $dst = $imm;;">; -def AND : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), - "and $dst = $src1, $src2;;">; -def OR : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), - "or $dst = $src1, $src2;;">; -def XOR : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), - "xor $dst = $src1, $src2;;">; -def SHL : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), - "shl $dst = $src1, $src2;;">; def SHLI : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, u6imm:$imm), "shl $dst = $src1, $imm;;">; -def SHRU : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), - "shr.u $dst = $src1, $src2;;">; def SHRUI : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, u6imm:$imm), "shr.u $dst = $src1, $imm;;">; -def SHRS : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), - "shr $dst = $src1, $src2;;">; def SHRSI : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, u6imm:$imm), "shr $dst = $src1, $imm;;">; -def SHLADD : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, u6imm:$imm, GR:$src2), - "shladd $dst = $src1, $imm, $src2;;">; - def EXTRU : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, u6imm:$imm1, u6imm:$imm2), "extr.u $dst = $src1, $imm1, $imm2;;">; def DEPZ : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, u6imm:$imm1, u6imm:$imm2), "dep.z $dst = $src1, $imm1, $imm2;;">; -def SXT1 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src), "sxt1 $dst = $src;;">; -def ZXT1 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src), "zxt1 $dst = $src;;">; -def SXT2 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src), "sxt2 $dst = $src;;">; -def ZXT2 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src), "zxt2 $dst = $src;;">; -def SXT4 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src), "sxt4 $dst = $src;;">; -def ZXT4 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src), "zxt4 $dst = $src;;">; - -// the following are all a bit unfortunate: we throw away the complement -// of the compare! -def CMPEQ : AForm<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), - "cmp.eq $dst, p0 = $src1, $src2;;">; -def CMPGT : AForm<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), - "cmp.gt $dst, p0 = $src1, $src2;;">; -def CMPGE : AForm<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), - "cmp.ge $dst, p0 = $src1, $src2;;">; -def CMPLT : AForm<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), - "cmp.lt $dst, p0 = $src1, $src2;;">; -def CMPLE : AForm<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), - "cmp.le $dst, p0 = $src1, $src2;;">; -def CMPNE : AForm<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), - "cmp.ne $dst, p0 = $src1, $src2;;">; -def CMPLTU : AForm<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), - "cmp.ltu $dst, p0 = $src1, $src2;;">; -def CMPGTU : AForm<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), - "cmp.gtu $dst, p0 = $src1, $src2;;">; -def CMPLEU : AForm<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), - "cmp.leu $dst, p0 = $src1, $src2;;">; -def CMPGEU : AForm<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2), - "cmp.geu $dst, p0 = $src1, $src2;;">; - -// and we do the whole thing again for FP compares! -def FCMPEQ : AForm<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), - "fcmp.eq $dst, p0 = $src1, $src2;;">; -def FCMPGT : AForm<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), - "fcmp.gt $dst, p0 = $src1, $src2;;">; -def FCMPGE : AForm<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), - "fcmp.ge $dst, p0 = $src1, $src2;;">; -def FCMPLT : AForm<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), - "fcmp.lt $dst, p0 = $src1, $src2;;">; -def FCMPLE : AForm<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), - "fcmp.le $dst, p0 = $src1, $src2;;">; -def FCMPNE : AForm<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), - "fcmp.neq $dst, p0 = $src1, $src2;;">; -def FCMPLTU : AForm<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), - "fcmp.ltu $dst, p0 = $src1, $src2;;">; -def FCMPGTU : AForm<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), - "fcmp.gtu $dst, p0 = $src1, $src2;;">; -def FCMPLEU : AForm<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), - "fcmp.leu $dst, p0 = $src1, $src2;;">; -def FCMPGEU : AForm<0x03, 0x0b, (ops PR:$dst, FP:$src1, FP:$src2), - "fcmp.geu $dst, p0 = $src1, $src2;;">; - def PCMPEQOR : AForm<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2, PR:$qp), "($qp) cmp.eq.or $dst, p0 = $src1, $src2;;">; def PCMPEQUNC : AForm<0x03, 0x0b, (ops PR:$dst, GR:$src1, GR:$src2, PR:$qp), @@ -186,8 +496,6 @@ def BCMPEQ : AForm<0x03, 0x0b, (ops PR:$dst1, PR:$dst2, GR:$src1, GR:$src2), "cmp.eq $dst1, dst2 = $src1, $src2;;">; -def ADD : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), - "add $dst = $src1, $src2;;">; def ADDIMM14 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, s14imm:$imm), "adds $dst = $imm, $src1;;">; @@ -196,63 +504,73 @@ def CADDIMM22 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, s22imm:$imm, PR:$qp), "($qp) add $dst = $imm, $src1;;">; -let isTwoAddress = 1 in { -def TPCADDIMM22 : AForm<0x03, 0x0b, - (ops GR:$dst, GR:$src1, s22imm:$imm, PR:$qp), - "($qp) add $dst = $imm, $dst;;">; -def TPCMPIMM8NE : AForm<0x03, 0x0b, - (ops PR:$dst, PR:$src1, s22imm:$imm, GR:$src2, PR:$qp), - "($qp) cmp.ne $dst , p0 = $imm, $src2;;">; -} - -def SUB : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2), - "sub $dst = $src1, $src2;;">; def SUBIMM8 : AForm<0x03, 0x0b, (ops GR:$dst, s8imm:$imm, GR:$src2), "sub $dst = $imm, $src2;;">; -def ST1 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value), - "st1 [$dstPtr] = $value;;">; -def ST2 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value), - "st2 [$dstPtr] = $value;;">; -def ST4 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value), - "st4 [$dstPtr] = $value;;">; -def ST8 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value), - "st8 [$dstPtr] = $value;;">; - -def LD1 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr), - "ld1 $dst = [$srcPtr];;">; -def LD2 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr), - "ld2 $dst = [$srcPtr];;">; -def LD4 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr), - "ld4 $dst = [$srcPtr];;">; -def LD8 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr), - "ld8 $dst = [$srcPtr];;">; - -def POPCNT : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src), "popcnt $dst = $src;;">; - -// some FP stuff: -def FADD : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2), - "fadd $dst = $src1, $src2;;">; +let isStore = 1 in { + def ST1 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value), + "st1 [$dstPtr] = $value;;">; + def ST2 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value), + "st2 [$dstPtr] = $value;;">; + def ST4 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value), + "st4 [$dstPtr] = $value;;">; + def ST8 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value), + "st8 [$dstPtr] = $value;;">; + def STF4 : AForm<0x03, 0x0b, (ops GR:$dstPtr, FP:$value), + "stfs [$dstPtr] = $value;;">; + def STF8 : AForm<0x03, 0x0b, (ops GR:$dstPtr, FP:$value), + "stfd [$dstPtr] = $value;;">; +} + +let isLoad = 1 in { + def LD1 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr), + "ld1 $dst = [$srcPtr];;">; + def LD2 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr), + "ld2 $dst = [$srcPtr];;">; + def LD4 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr), + "ld4 $dst = [$srcPtr];;">; + def LD8 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr), + "ld8 $dst = [$srcPtr];;">; + def LDF4 : AForm<0x03, 0x0b, (ops FP:$dst, GR:$srcPtr), + "ldfs $dst = [$srcPtr];;">; + def LDF8 : AForm<0x03, 0x0b, (ops FP:$dst, GR:$srcPtr), + "ldfd $dst = [$srcPtr];;">; +} + +def POPCNT : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src), + "popcnt $dst = $src;;", + [(set GR:$dst, (ctpop GR:$src))]>; + +// some FP stuff: // TODO: single-precision stuff? +def FADD : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2), + "fadd $dst = $src1, $src2;;", + [(set FP:$dst, (fadd FP:$src1, FP:$src2))]>; def FADDS: AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2), "fadd.s $dst = $src1, $src2;;">; -def FSUB : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2), - "fsub $dst = $src1, $src2;;">; -def FMPY : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2), - "fmpy $dst = $src1, $src2;;">; -def FMOV : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), - "mov $dst = $src;;">; // XXX: there _is_ no fmov -def FMA : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), - "fma $dst = $src1, $src2, $src3;;">; -def FMS : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), - "fms $dst = $src1, $src2, $src3;;">; -def FNMA : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), - "fnma $dst = $src1, $src2, $src3;;">; -def FABS : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), - "fabs $dst = $src;;">; -def FNEG : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), - "fneg $dst = $src;;">; -def FNEGABS : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), - "fnegabs $dst = $src;;">; +def FSUB : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2), + "fsub $dst = $src1, $src2;;", + [(set FP:$dst, (fsub FP:$src1, FP:$src2))]>; +def FMPY : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2), + "fmpy $dst = $src1, $src2;;", + [(set FP:$dst, (fmul FP:$src1, FP:$src2))]>; +def FMA : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), + "fma $dst = $src1, $src2, $src3;;", + [(set FP:$dst, (fadd (fmul FP:$src1, FP:$src2), FP:$src3))]>; +def FMS : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), + "fms $dst = $src1, $src2, $src3;;", + [(set FP:$dst, (fsub (fmul FP:$src1, FP:$src2), FP:$src3))]>; +def FNMA : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), + "fnma $dst = $src1, $src2, $src3;;", + [(set FP:$dst, (fneg (fadd (fmul FP:$src1, FP:$src2), FP:$src3)))]>; +def FABS : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src), + "fabs $dst = $src;;", + [(set FP:$dst, (fabs FP:$src))]>; +def FNEG : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src), + "fneg $dst = $src;;", + [(set FP:$dst, (fneg FP:$src))]>; +def FNEGABS : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src), + "fnegabs $dst = $src;;", + [(set FP:$dst, (fneg (fabs FP:$src)))]>; def CFMAS1 : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3, PR:$qp), @@ -301,17 +619,20 @@ def SETFSIG : AForm<0x03, 0x0b, (ops FP:$dst, GR:$src), "setf.sig $dst = $src;;">; -def LDF4 : AForm<0x03, 0x0b, (ops FP:$dst, GR:$srcPtr), - "ldfs $dst = [$srcPtr];;">; -def LDF8 : AForm<0x03, 0x0b, (ops FP:$dst, GR:$srcPtr), - "ldfd $dst = [$srcPtr];;">; - -def STF4 : AForm<0x03, 0x0b, (ops GR:$dstPtr, FP:$value), - "stfs [$dstPtr] = $value;;">; -def STF8 : AForm<0x03, 0x0b, (ops GR:$dstPtr, FP:$value), - "stfd [$dstPtr] = $value;;">; +// these four FP<->int conversion patterns need checking/cleaning +def SINT_TO_FP : Pat<(sint_to_fp GR:$src), + (FNORMD (FCVTXF (SETFSIG GR:$src)))>; +def UINT_TO_FP : Pat<(uint_to_fp GR:$src), + (FNORMD (FCVTXUF (SETFSIG GR:$src)))>; +def FP_TO_SINT : Pat<(i64 (fp_to_sint FP:$src)), + (GETFSIG (FCVTFXTRUNC FP:$src))>; +def FP_TO_UINT : Pat<(i64 (fp_to_uint FP:$src)), + (GETFSIG (FCVTFXUTRUNC FP:$src))>; + let isTerminator = 1, isBranch = 1 in { + def BRL_NOTCALL : RawForm<0x03, 0xb0, (ops i64imm:$dst), + "(p0) brl.cond.sptk $dst;;">; def BRLCOND_NOTCALL : RawForm<0x03, 0xb0, (ops PR:$qp, i64imm:$dst), "($qp) brl.cond.sptk $dst;;">; def BRCOND_NOTCALL : RawForm<0x03, 0xb0, (ops PR:$qp, GR:$dst), @@ -334,8 +655,14 @@ F106,F107,F108,F109,F110,F111,F112,F113,F114,F115,F116,F117,F118,F119, F120,F121,F122,F123,F124,F125,F126,F127, out0,out1,out2,out3,out4,out5,out6,out7] in { - def BRCALL : RawForm<0x03, 0xb0, (ops calltarget:$dst), +// old pattern call + def BRCALL: RawForm<0x03, 0xb0, (ops calltarget:$dst), + "br.call.sptk rp = $dst;;">; // FIXME: teach llvm about branch regs? +// new daggy stuff! + def BRCALL_IPREL : RawForm<0x03, 0xb0, (ops calltarget:$dst, variable_ops), "br.call.sptk rp = $dst;;">; // FIXME: teach llvm about branch regs? + def BRCALL_INDIRECT : RawForm<0x03, 0xb0, (ops GR:$branchreg, variable_ops), + "br.call.sptk rp = $branchreg;;">; // FIXME: teach llvm about branch regs? def BRLCOND_CALL : RawForm<0x03, 0xb0, (ops PR:$qp, i64imm:$dst), "($qp) brl.cond.call.sptk $dst;;">; def BRCOND_CALL : RawForm<0x03, 0xb0, (ops PR:$qp, GR:$dst), Index: llvm/lib/Target/IA64/IA64RegisterInfo.cpp diff -u llvm/lib/Target/IA64/IA64RegisterInfo.cpp:1.7 llvm/lib/Target/IA64/IA64RegisterInfo.cpp:1.7.2.1 --- llvm/lib/Target/IA64/IA64RegisterInfo.cpp:1.7 Thu Sep 29 20:30:29 2005 +++ llvm/lib/Target/IA64/IA64RegisterInfo.cpp Wed Nov 16 12:32:36 2005 @@ -28,38 +28,23 @@ #include "llvm/Support/CommandLine.h" #include "llvm/ADT/STLExtras.h" #include - using namespace llvm; -namespace { -} IA64RegisterInfo::IA64RegisterInfo() : IA64GenRegisterInfo(IA64::ADJUSTCALLSTACKDOWN, IA64::ADJUSTCALLSTACKUP) {} -static const TargetRegisterClass *getClass(unsigned SrcReg) { - if (IA64::FPRegisterClass->contains(SrcReg)) - return IA64::FPRegisterClass; - if (IA64::PRRegisterClass->contains(SrcReg)) - return IA64::PRRegisterClass; - - assert(IA64::GRRegisterClass->contains(SrcReg) && - "PROBLEM: Reg is not FP, predicate or GR!"); - return IA64::GRRegisterClass; -} - void IA64RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, int FrameIdx, const TargetRegisterClass *RC) const{ - if (getClass(SrcReg) == IA64::FPRegisterClass) { + if (RC == IA64::FPRegisterClass) { BuildMI(MBB, MI, IA64::STF8, 2).addFrameIndex(FrameIdx).addReg(SrcReg); - } - else if (getClass(SrcReg) == IA64::GRRegisterClass) { + } else if (RC == IA64::GRRegisterClass) { BuildMI(MBB, MI, IA64::ST8, 2).addFrameIndex(FrameIdx).addReg(SrcReg); } - else if (getClass(SrcReg) == IA64::PRRegisterClass) { + else if (RC == IA64::PRRegisterClass) { /* we use IA64::r2 as a temporary register for doing this hackery. */ // first we load 0: BuildMI(MBB, MI, IA64::MOV, 1, IA64::r2).addReg(IA64::r0); @@ -77,11 +62,11 @@ unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC)const{ - if (getClass(DestReg) == IA64::FPRegisterClass) { + if (RC == IA64::FPRegisterClass) { BuildMI(MBB, MI, IA64::LDF8, 1, DestReg).addFrameIndex(FrameIdx); - } else if (getClass(DestReg) == IA64::GRRegisterClass) { + } else if (RC == IA64::GRRegisterClass) { BuildMI(MBB, MI, IA64::LD8, 1, DestReg).addFrameIndex(FrameIdx); - } else if (getClass(DestReg) == IA64::PRRegisterClass) { + } else if (RC == IA64::PRRegisterClass) { // first we load a byte from the stack into r2, our 'predicate hackery' // scratch reg BuildMI(MBB, MI, IA64::LD8, 1, IA64::r2).addFrameIndex(FrameIdx); Index: llvm/lib/Target/IA64/IA64RegisterInfo.td diff -u llvm/lib/Target/IA64/IA64RegisterInfo.td:1.8 llvm/lib/Target/IA64/IA64RegisterInfo.td:1.8.2.1 --- llvm/lib/Target/IA64/IA64RegisterInfo.td:1.8 Fri Aug 19 14:13:20 2005 +++ llvm/lib/Target/IA64/IA64RegisterInfo.td Wed Nov 16 12:32:36 2005 @@ -211,7 +211,7 @@ // application (special) registers: -// " previous function state" application register +// "previous function state" application register def AR_PFS : GR<0, "ar.pfs">; // "return pointer" (this is really branch register b0) @@ -226,7 +226,6 @@ // // these are the scratch (+stacked) general registers -// ZERO (r0), GP (r1), SP (r12), ThreadP (r13) are not here... // FIXME/XXX we also reserve a frame pointer (r15) // FIXME/XXX we also reserve r2 for spilling/filling predicates // in IA64RegisterInfo.cpp @@ -255,7 +254,7 @@ r104, r105, r106, r107, r108, r109, r110, r111, r112, r113, r114, r115, r116, r117, r118, r119, r120, r121, r122, r123, r124, r125, r126, r127, - r0, r1, r2, r12, r13, r15, r22]> // the last 15 are special (look down) + r0, r1, r2, r12, r13, r15, r22, rp]> // the last 16 are special (look down) { let MethodProtos = [{ iterator allocation_order_begin(MachineFunction &MF) const; @@ -264,13 +263,13 @@ let MethodBodies = [{ GRClass::iterator GRClass::allocation_order_begin(MachineFunction &MF) const { - // hide registers appropriately: + // hide the 8 out? registers appropriately: return begin()+(8-(MF.getInfo()->outRegsUsed)); } GRClass::iterator GRClass::allocation_order_end(MachineFunction &MF) const { - int numReservedRegs=7; // the 7 special registers r0,r1,r2,r12,r13 etc + int numReservedRegs=8; // the 8 special registers r0,r1,r2,r12,r13 etc // we also can't allocate registers for use as locals if they're // already required as 'out' registers @@ -283,7 +282,6 @@ // these are the scratch (+stacked) FP registers -// ZERO (F0) and ONE (F1) are not here def FP : RegisterClass<"IA64", f64, 64, [F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, @@ -298,7 +296,25 @@ F96, F97, F98, F99, F100, F101, F102, F103, F104, F105, F106, F107, F108, F109, F110, F111, F112, F113, F114, F115, F116, F117, F118, F119, - F120, F121, F122, F123, F124, F125, F126, F127]>; + F120, F121, F122, F123, F124, F125, F126, F127, + F0, F1]> // these last two are hidden + { + let MethodProtos = [{ + iterator allocation_order_begin(MachineFunction &MF) const; + iterator allocation_order_end(MachineFunction &MF) const; + }]; + let MethodBodies = [{ + FPClass::iterator + FPClass::allocation_order_begin(MachineFunction &MF) const { + return begin(); // we don't hide any FP regs from the start + } + + FPClass::iterator + FPClass::allocation_order_end(MachineFunction &MF) const { + return end()-2; // we hide regs F0, F1 from the end + } + }]; +} // these are the predicate registers, p0 (1/TRUE) is not here def PR : RegisterClass<"IA64", i1, 64, Index: llvm/lib/Target/IA64/IA64TargetMachine.cpp diff -u llvm/lib/Target/IA64/IA64TargetMachine.cpp:1.5 llvm/lib/Target/IA64/IA64TargetMachine.cpp:1.5.2.1 --- llvm/lib/Target/IA64/IA64TargetMachine.cpp:1.5 Thu Sep 1 16:38:20 2005 +++ llvm/lib/Target/IA64/IA64TargetMachine.cpp Wed Nov 16 12:32:36 2005 @@ -37,6 +37,9 @@ cl::desc("Disable the IA64 asm printer, for use " "when profiling the code generator.")); + cl::opt EnableDAGIsel("enable-ia64-dag-isel", cl::Hidden, + cl::desc("Enable the IA64 DAG->DAG isel")); + // Register the target. RegisterTarget X("ia64", " IA-64 (Itanium)"); } @@ -82,14 +85,16 @@ // does to emit statically compiled machine code. bool IA64TargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType) { + CodeGenFileType FileType, + bool Fast) { if (FileType != TargetMachine::AssemblyFile) return true; // FIXME: Implement efficient support for garbage collection intrinsics. PM.add(createLowerGCPass()); // FIXME: Implement the invoke/unwind instructions! - PM.add(createLowerInvokePass()); + PM.add(createLowerInvokePass(704, 16)); // on ia64 linux, jmpbufs are 704 + // bytes and must be 16byte aligned // FIXME: Implement the switch instruction in the instruction selector! PM.add(createLowerSwitchPass()); @@ -97,8 +102,12 @@ // Make sure that no unreachable blocks are instruction selected. PM.add(createUnreachableBlockEliminationPass()); - PM.add(createIA64PatternInstructionSelector(*this)); - + // Add an instruction selector + if(EnableDAGIsel) + PM.add(createIA64DAGToDAGInstructionSelector(*this)); + else + PM.add(createIA64PatternInstructionSelector(*this)); + /* XXX not yet. ;) // Run optional SSA-based machine code optimizations next... if (!NoSSAPeephole) Index: llvm/lib/Target/IA64/IA64TargetMachine.h diff -u llvm/lib/Target/IA64/IA64TargetMachine.h:1.4 llvm/lib/Target/IA64/IA64TargetMachine.h:1.4.2.1 --- llvm/lib/Target/IA64/IA64TargetMachine.h:1.4 Thu Sep 1 16:38:20 2005 +++ llvm/lib/Target/IA64/IA64TargetMachine.h Wed Nov 16 12:32:36 2005 @@ -37,7 +37,7 @@ } virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType); + CodeGenFileType FileType, bool Fast); static unsigned getModuleMatchQuality(const Module &M); static unsigned compileTimeMatchQuality(void); Index: llvm/lib/Target/IA64/Makefile diff -u llvm/lib/Target/IA64/Makefile:1.3 llvm/lib/Target/IA64/Makefile:1.3.4.1 --- llvm/lib/Target/IA64/Makefile:1.3 Thu Mar 17 12:37:05 2005 +++ llvm/lib/Target/IA64/Makefile Wed Nov 16 12:32:36 2005 @@ -11,7 +11,8 @@ # Make sure that tblgen is run, first thing. BUILT_SOURCES = IA64GenRegisterInfo.h.inc IA64GenRegisterNames.inc \ IA64GenRegisterInfo.inc IA64GenInstrNames.inc \ - IA64GenInstrInfo.inc IA64GenAsmWriter.inc + IA64GenInstrInfo.inc IA64GenAsmWriter.inc \ + IA64GenDAGISel.inc include $(LEVEL)/Makefile.common Index: llvm/lib/Target/IA64/README diff -u llvm/lib/Target/IA64/README:1.4 llvm/lib/Target/IA64/README:1.4.4.1 --- llvm/lib/Target/IA64/README:1.4 Tue Apr 12 13:42:59 2005 +++ llvm/lib/Target/IA64/README Wed Nov 16 12:32:36 2005 @@ -54,6 +54,8 @@ TODO: + - stop passing FP args in both FP *and* integer regs when not required + - allocate low (nonstacked) registers more aggressively - clean up and thoroughly test the isel patterns. - fix stacked register allocation order: (for readability) we don't want the out? registers being the first ones used @@ -62,7 +64,7 @@ - bundling! (we will avoid the mess that is: http://gcc.gnu.org/ml/gcc/2003-12/msg00832.html ) - - instruction scheduling (yep) + - instruction scheduling (hmmmm! ;) - write truly inspirational documentation - if-conversion (predicate database/knowledge? etc etc) - counted loop support From bocchino at cs.uiuc.edu Wed Nov 16 12:32:44 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:44 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Target/Alpha/Alpha.h Alpha.td AlphaISelDAGToDAG.cpp AlphaISelLowering.cpp AlphaISelLowering.h AlphaISelPattern.cpp AlphaInstrFormats.td AlphaInstrInfo.cpp AlphaInstrInfo.td AlphaRegisterInfo.cpp AlphaRegisterInfo.h AlphaRegisterInfo.td AlphaSubtarget.cpp AlphaSubtarget.h AlphaTargetMachine.cpp AlphaTargetMachine.h Makefile Message-ID: <200511161832.MAA21034@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: Alpha.h updated: 1.4 -> 1.4.2.1 Alpha.td updated: 1.4 -> 1.4.2.1 AlphaISelDAGToDAG.cpp added (r1.5.4.2) AlphaISelLowering.cpp updated: 1.7 -> 1.7.2.1 AlphaISelLowering.h updated: 1.1 -> 1.1.2.1 AlphaISelPattern.cpp updated: 1.173 -> 1.173.2.1 AlphaInstrFormats.td updated: 1.6 -> 1.6.2.1 AlphaInstrInfo.cpp updated: 1.5 -> 1.5.4.1 AlphaInstrInfo.td updated: 1.59 -> 1.59.2.1 AlphaRegisterInfo.cpp updated: 1.28 -> 1.28.2.1 AlphaRegisterInfo.h updated: 1.7 -> 1.7.2.1 AlphaRegisterInfo.td updated: 1.12 -> 1.12.2.1 AlphaSubtarget.cpp updated: 1.3 -> 1.3.2.1 AlphaSubtarget.h updated: 1.1 -> 1.1.2.1 AlphaTargetMachine.cpp updated: 1.13 -> 1.13.2.1 AlphaTargetMachine.h updated: 1.10 -> 1.10.2.1 Makefile updated: 1.2 -> 1.2.4.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+996 -530) Alpha.h | 1 Alpha.td | 24 + AlphaISelDAGToDAG.cpp | 288 ++++++++++++++++++++++ AlphaISelLowering.cpp | 4 AlphaISelLowering.h | 9 AlphaISelPattern.cpp | 253 +++++-------------- AlphaInstrFormats.td | 96 ++++--- AlphaInstrInfo.cpp | 4 AlphaInstrInfo.td | 632 +++++++++++++++++++++++++++++++------------------ AlphaRegisterInfo.cpp | 71 ++++- AlphaRegisterInfo.h | 3 AlphaRegisterInfo.td | 55 +++- AlphaSubtarget.cpp | 44 --- AlphaSubtarget.h | 4 AlphaTargetMachine.cpp | 27 +- AlphaTargetMachine.h | 8 Makefile | 3 17 files changed, 996 insertions(+), 530 deletions(-) Index: llvm/lib/Target/Alpha/Alpha.h diff -u llvm/lib/Target/Alpha/Alpha.h:1.4 llvm/lib/Target/Alpha/Alpha.h:1.4.2.1 --- llvm/lib/Target/Alpha/Alpha.h:1.4 Fri Jul 22 15:52:16 2005 +++ llvm/lib/Target/Alpha/Alpha.h Wed Nov 16 12:32:33 2005 @@ -24,6 +24,7 @@ class MachineCodeEmitter; FunctionPass *createAlphaSimpleInstructionSelector(TargetMachine &TM); + FunctionPass *createAlphaISelDag(TargetMachine &TM); FunctionPass *createAlphaCodePrinterPass(std::ostream &OS, TargetMachine &TM); FunctionPass *createAlphaPatternInstructionSelector(TargetMachine &TM); Index: llvm/lib/Target/Alpha/Alpha.td diff -u llvm/lib/Target/Alpha/Alpha.td:1.4 llvm/lib/Target/Alpha/Alpha.td:1.4.2.1 --- llvm/lib/Target/Alpha/Alpha.td:1.4 Thu Jun 23 18:42:05 2005 +++ llvm/lib/Target/Alpha/Alpha.td Wed Nov 16 12:32:33 2005 @@ -17,6 +17,15 @@ //Alpha is little endian //===----------------------------------------------------------------------===// +// Subtarget Features +//===----------------------------------------------------------------------===// + +def FeatureCIX : SubtargetFeature<"CIX", "bool", "HasCT", + "Enable CIX extentions">; +def FeatureFIX : SubtargetFeature<"FIX", "bool", "HasF2I", + "Enable FIX extentions">; + +//===----------------------------------------------------------------------===// // Register File Description //===----------------------------------------------------------------------===// @@ -36,6 +45,21 @@ // let TSFlagsShifts = []; } +//===----------------------------------------------------------------------===// +// Alpha Processor Definitions +//===----------------------------------------------------------------------===// + +def : Processor<"generic", NoItineraries, []>; +def : Processor<"pca56" , NoItineraries, []>; +def : Processor<"ev56" , NoItineraries, []>; +def : Processor<"ev6" , NoItineraries, [FeatureFIX]>; +def : Processor<"ev67" , NoItineraries, [FeatureFIX, FeatureCIX]>; + +//===----------------------------------------------------------------------===// +// The Alpha Target +//===----------------------------------------------------------------------===// + + def Alpha : Target { // Pointers on Alpha are 64-bits in size. let PointerType = i64; Index: llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp diff -c /dev/null llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp:1.5.4.2 *** /dev/null Wed Nov 16 12:32:44 2005 --- llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp Wed Nov 16 12:32:33 2005 *************** *** 0 **** --- 1,288 ---- + //===-- AlphaISelDAGToDAG.cpp - Alpha pattern matching inst selector ------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Andrew Lenharth and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file defines a pattern matching instruction selector for Alpha, + // converting from a legalized dag to a Alpha dag. + // + //===----------------------------------------------------------------------===// + + #include "Alpha.h" + #include "AlphaTargetMachine.h" + #include "AlphaISelLowering.h" + #include "llvm/CodeGen/MachineInstrBuilder.h" + #include "llvm/CodeGen/MachineFunction.h" + #include "llvm/CodeGen/SSARegMap.h" + #include "llvm/CodeGen/SelectionDAG.h" + #include "llvm/CodeGen/SelectionDAGISel.h" + #include "llvm/Target/TargetOptions.h" + #include "llvm/ADT/Statistic.h" + #include "llvm/Constants.h" + #include "llvm/GlobalValue.h" + #include "llvm/Support/Debug.h" + #include "llvm/Support/MathExtras.h" + #include + using namespace llvm; + + namespace { + + //===--------------------------------------------------------------------===// + /// AlphaDAGToDAGISel - Alpha specific code to select Alpha machine + /// instructions for SelectionDAG operations. + /// + class AlphaDAGToDAGISel : public SelectionDAGISel { + AlphaTargetLowering AlphaLowering; + + public: + AlphaDAGToDAGISel(TargetMachine &TM) + : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {} + + /// getI64Imm - Return a target constant with the specified value, of type + /// i64. + inline SDOperand getI64Imm(int64_t Imm) { + return CurDAG->getTargetConstant(Imm, MVT::i64); + } + + // Select - Convert the specified operand from a target-independent to a + // target-specific node if it hasn't already been changed. + SDOperand Select(SDOperand Op); + + /// InstructionSelectBasicBlock - This callback is invoked by + /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. + virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); + + virtual const char *getPassName() const { + return "Alpha DAG->DAG Pattern Instruction Selection"; + } + + // Include the pieces autogenerated from the target description. + #include "AlphaGenDAGISel.inc" + + private: + SDOperand getGlobalBaseReg(); + SDOperand SelectCALL(SDOperand Op); + + }; + } + + /// getGlobalBaseReg - Output the instructions required to put the + /// GOT address into a register. + /// + SDOperand AlphaDAGToDAGISel::getGlobalBaseReg() { + return CurDAG->getRegister(AlphaLowering.getVRegGP(), MVT::i64); + } + + /// InstructionSelectBasicBlock - This callback is invoked by + /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. + void AlphaDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { + DEBUG(BB->dump()); + + // Select target instructions for the DAG. + DAG.setRoot(Select(DAG.getRoot())); + CodeGenMap.clear(); + DAG.RemoveDeadNodes(); + + // Emit machine code to BB. + ScheduleAndEmitDAG(DAG); + } + + // Select - Convert the specified operand from a target-independent to a + // target-specific node if it hasn't already been changed. + SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) { + SDNode *N = Op.Val; + if (N->getOpcode() >= ISD::BUILTIN_OP_END && + N->getOpcode() < AlphaISD::FIRST_NUMBER) + return Op; // Already selected. + + // If this has already been converted, use it. + std::map::iterator CGMI = CodeGenMap.find(Op); + if (CGMI != CodeGenMap.end()) return CGMI->second; + + switch (N->getOpcode()) { + default: break; + case ISD::TAILCALL: + case ISD::CALL: return SelectCALL(Op); + + case ISD::DYNAMIC_STACKALLOC: + assert(0 && "You want these too?"); + + case ISD::BRCOND: { + SDOperand Chain = Select(N->getOperand(0)); + SDOperand CC = Select(N->getOperand(1)); + CurDAG->SelectNodeTo(N, Alpha::BNE, MVT::Other, CC, Chain); + return SDOperand(N, 0); + } + case ISD::LOAD: + case ISD::EXTLOAD: + case ISD::ZEXTLOAD: + case ISD::SEXTLOAD: { + SDOperand Chain = Select(N->getOperand(0)); + SDOperand Address = Select(N->getOperand(1)); + unsigned opcode = N->getOpcode(); + unsigned Opc = Alpha::WTF; + if (opcode == ISD::LOAD) + switch (N->getValueType(0)) { + default: N->dump(); assert(0 && "Bad load!"); + case MVT::i64: Opc = Alpha::LDQ; break; + case MVT::f64: Opc = Alpha::LDT; break; + case MVT::f32: Opc = Alpha::LDS; break; + } + else + switch (cast(N->getOperand(3))->getVT()) { + default: N->dump(); assert(0 && "Bad sign extend!"); + case MVT::i32: Opc = Alpha::LDL; + assert(opcode != ISD::ZEXTLOAD && "Not sext"); break; + case MVT::i16: Opc = Alpha::LDWU; + assert(opcode != ISD::SEXTLOAD && "Not zext"); break; + case MVT::i1: //FIXME: Treat i1 as i8 since there are problems otherwise + case MVT::i8: Opc = Alpha::LDBU; + assert(opcode != ISD::SEXTLOAD && "Not zext"); break; + } + + CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other, + getI64Imm(0), Address, Chain); + return SDOperand(N, Op.ResNo); + } + + case ISD::BR: { + CurDAG->SelectNodeTo(N, Alpha::BR_DAG, MVT::Other, N->getOperand(1), + Select(N->getOperand(0))); + return SDOperand(N, 0); + } + + case ISD::UNDEF: + if (N->getValueType(0) == MVT::i64) + CurDAG->SelectNodeTo(N, Alpha::IDEF, MVT::i64); + // else if (N->getValueType(0) == MVT::f32) + // CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F4, MVT::f32); + // else + // CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F8, MVT::f64); + return SDOperand(N, 0); + case ISD::FrameIndex: { + // int FI = cast(N)->getIndex(); + // CurDAG->SelectNodeTo(N, Alpha::LDA, MVT::i64, + // CurDAG->getTargetFrameIndex(FI, MVT::i32), + // getI32Imm(0)); + // return SDOperand(N, 0); + assert(0 && "Frame?, you are suppose to look through the window, not at the frame!"); + } + case ISD::ConstantPool: { + // Constant *C = cast(N)->get(); + // SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(C, MVT::i32); + // if (PICEnabled) + // Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(),CPI); + // else + // Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, CPI); + // CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, CPI); + // return SDOperand(N, 0); + assert(0 && "Constants are overrated"); + } + case ISD::GlobalAddress: { + GlobalValue *GV = cast(N)->getGlobal(); + SDOperand GA = CurDAG->getTargetGlobalAddress(GV, MVT::i64); + CurDAG->SelectNodeTo(N, Alpha::LDQl, MVT::i64, GA, getGlobalBaseReg()); + return SDOperand(N, 0); + } + case ISD::ExternalSymbol: + CurDAG->SelectNodeTo(N, Alpha::LDQl, MVT::i64, + CurDAG->getTargetExternalSymbol(cast(N)->getSymbol(), MVT::i64), + CurDAG->getRegister(AlphaLowering.getVRegGP(), MVT::i64)); + return SDOperand(N, 0); + + case ISD::CALLSEQ_START: + case ISD::CALLSEQ_END: { + unsigned Amt = cast(N->getOperand(1))->getValue(); + unsigned Opc = N->getOpcode() == ISD::CALLSEQ_START ? + Alpha::ADJUSTSTACKDOWN : Alpha::ADJUSTSTACKUP; + CurDAG->SelectNodeTo(N, Opc, MVT::Other, + getI64Imm(Amt), Select(N->getOperand(0))); + return SDOperand(N, 0); + } + case ISD::RET: { + SDOperand Chain = Select(N->getOperand(0)); // Token chain. + + if (N->getNumOperands() == 2) { + SDOperand Val = Select(N->getOperand(1)); + if (N->getOperand(1).getValueType() == MVT::i64) { + Chain = CurDAG->getCopyToReg(Chain, Alpha::R0, Val); + } + } + //BuildMI(BB, Alpha::RET, 2, Alpha::R31).addReg(Alpha::R26).addImm(1); + + // FIXME: add restoring of the RA to R26 to the chain + // Finally, select this to a ret instruction. + CurDAG->SelectNodeTo(N, Alpha::RETDAG, MVT::Other, Chain); + return SDOperand(N, 0); + } + + + + } + + return SelectCode(Op); + } + + SDOperand AlphaDAGToDAGISel::SelectCALL(SDOperand Op) { + SDNode *N = Op.Val; + SDOperand Chain = Select(N->getOperand(0)); + SDOperand Addr = Select(N->getOperand(1)); + + // unsigned CallOpcode; + std::vector CallOperands; + std::vector TypeOperands; + + //grab the arguments + for(int i = 2, e = N->getNumOperands(); i < e; ++i) { + TypeOperands.push_back(N->getOperand(i).getValueType()); + CallOperands.push_back(Select(N->getOperand(i))); + } + int count = N->getNumOperands() - 2; + + static const unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18, + Alpha::R19, Alpha::R20, Alpha::R21}; + static const unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18, + Alpha::F19, Alpha::F20, Alpha::F21}; + + for (int i = 0; i < std::min(6, count); ++i) { + if (MVT::isInteger(TypeOperands[i])) { + Chain = CurDAG->getCopyToReg(Chain, args_int[i], CallOperands[i]); + } else { + assert(0 && "No FP support yet"); + } + } + assert(CallOperands.size() <= 6 && "Too big a call"); + + Chain = CurDAG->getCopyToReg(Chain, Alpha::R27, Addr); + // Finally, once everything is in registers to pass to the call, emit the + // call itself. + Chain = CurDAG->getTargetNode(Alpha::JSRDAG, MVT::Other, Chain ); + + std::vector CallResults; + + switch (N->getValueType(0)) { + default: assert(0 && "Unexpected ret value!"); + case MVT::Other: break; + case MVT::i64: + Chain = CurDAG->getCopyFromReg(Chain, Alpha::R0, MVT::i64).getValue(1); + CallResults.push_back(Chain.getValue(0)); + break; + } + + CallResults.push_back(Chain); + for (unsigned i = 0, e = CallResults.size(); i != e; ++i) + CodeGenMap[Op.getValue(i)] = CallResults[i]; + return CallResults[Op.ResNo]; + } + + + /// createAlphaISelDag - This pass converts a legalized DAG into a + /// Alpha-specific DAG, ready for instruction scheduling. + /// + FunctionPass *llvm::createAlphaISelDag(TargetMachine &TM) { + return new AlphaDAGToDAGISel(TM); + } Index: llvm/lib/Target/Alpha/AlphaISelLowering.cpp diff -u llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.7 llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.7.2.1 --- llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.7 Thu Oct 6 11:54:29 2005 +++ llvm/lib/Target/Alpha/AlphaISelLowering.cpp Wed Nov 16 12:32:33 2005 @@ -50,8 +50,8 @@ setSetCCResultContents(ZeroOrOneSetCCResult); addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass); - addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass); - addRegisterClass(MVT::f32, Alpha::FPRCRegisterClass); + addRegisterClass(MVT::f64, Alpha::F8RCRegisterClass); + addRegisterClass(MVT::f32, Alpha::F4RCRegisterClass); setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand); setOperationAction(ISD::BRTWOWAY_CC, MVT::Other, Expand); Index: llvm/lib/Target/Alpha/AlphaISelLowering.h diff -u llvm/lib/Target/Alpha/AlphaISelLowering.h:1.1 llvm/lib/Target/Alpha/AlphaISelLowering.h:1.1.2.1 --- llvm/lib/Target/Alpha/AlphaISelLowering.h:1.1 Fri Sep 2 13:46:02 2005 +++ llvm/lib/Target/Alpha/AlphaISelLowering.h Wed Nov 16 12:32:33 2005 @@ -21,6 +21,13 @@ namespace llvm { + namespace AlphaISD { + enum NodeType { + // Start the numbering where the builting ops and target ops leave off. + FIRST_NUMBER = ISD::BUILTIN_OP_END+Alpha::INSTRUCTION_LIST_END, + }; + } + class AlphaTargetLowering : public TargetLowering { int VarArgsOffset; // What is the offset to the first vaarg int VarArgsBase; // What is the base FrameIndex @@ -52,6 +59,8 @@ void restoreGP(MachineBasicBlock* BB); void restoreRA(MachineBasicBlock* BB); + unsigned getVRegGP() { return GP; } + unsigned getVRegRA() { return RA; } }; } Index: llvm/lib/Target/Alpha/AlphaISelPattern.cpp diff -u llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.173 llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.173.2.1 --- llvm/lib/Target/Alpha/AlphaISelPattern.cpp:1.173 Thu Oct 6 11:54:29 2005 +++ llvm/lib/Target/Alpha/AlphaISelPattern.cpp Wed Nov 16 12:32:33 2005 @@ -82,6 +82,10 @@ AlphaLowering(TM) {} + virtual const char *getPassName() const { + return "Alpha Pattern Instruction Selection"; + } + /// InstructionSelectBasicBlock - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) { @@ -235,152 +239,6 @@ } -//Shamelessly adapted from PPC32 -// Structure used to return the necessary information to codegen an SDIV as -// a multiply. -struct ms { - int64_t m; // magic number - int64_t s; // shift amount -}; - -struct mu { - uint64_t m; // magic number - int64_t a; // add indicator - int64_t s; // shift amount -}; - -/// magic - calculate the magic numbers required to codegen an integer sdiv as -/// a sequence of multiply and shifts. Requires that the divisor not be 0, 1, -/// or -1. -static struct ms magic(int64_t d) { - int64_t p; - uint64_t ad, anc, delta, q1, r1, q2, r2, t; - const uint64_t two63 = 9223372036854775808ULL; // 2^63 - struct ms mag; - - ad = llabs(d); - t = two63 + ((uint64_t)d >> 63); - anc = t - 1 - t%ad; // absolute value of nc - p = 63; // initialize p - q1 = two63/anc; // initialize q1 = 2p/abs(nc) - r1 = two63 - q1*anc; // initialize r1 = rem(2p,abs(nc)) - q2 = two63/ad; // initialize q2 = 2p/abs(d) - r2 = two63 - q2*ad; // initialize r2 = rem(2p,abs(d)) - do { - p = p + 1; - q1 = 2*q1; // update q1 = 2p/abs(nc) - r1 = 2*r1; // update r1 = rem(2p/abs(nc)) - if (r1 >= anc) { // must be unsigned comparison - q1 = q1 + 1; - r1 = r1 - anc; - } - q2 = 2*q2; // update q2 = 2p/abs(d) - r2 = 2*r2; // update r2 = rem(2p/abs(d)) - if (r2 >= ad) { // must be unsigned comparison - q2 = q2 + 1; - r2 = r2 - ad; - } - delta = ad - r2; - } while (q1 < delta || (q1 == delta && r1 == 0)); - - mag.m = q2 + 1; - if (d < 0) mag.m = -mag.m; // resulting magic number - mag.s = p - 64; // resulting shift - return mag; -} - -/// magicu - calculate the magic numbers required to codegen an integer udiv as -/// a sequence of multiply, add and shifts. Requires that the divisor not be 0. -static struct mu magicu(uint64_t d) -{ - int64_t p; - uint64_t nc, delta, q1, r1, q2, r2; - struct mu magu; - magu.a = 0; // initialize "add" indicator - nc = - 1 - (-d)%d; - p = 63; // initialize p - q1 = 0x8000000000000000ull/nc; // initialize q1 = 2p/nc - r1 = 0x8000000000000000ull - q1*nc; // initialize r1 = rem(2p,nc) - q2 = 0x7FFFFFFFFFFFFFFFull/d; // initialize q2 = (2p-1)/d - r2 = 0x7FFFFFFFFFFFFFFFull - q2*d; // initialize r2 = rem((2p-1),d) - do { - p = p + 1; - if (r1 >= nc - r1 ) { - q1 = 2*q1 + 1; // update q1 - r1 = 2*r1 - nc; // update r1 - } - else { - q1 = 2*q1; // update q1 - r1 = 2*r1; // update r1 - } - if (r2 + 1 >= d - r2) { - if (q2 >= 0x7FFFFFFFFFFFFFFFull) magu.a = 1; - q2 = 2*q2 + 1; // update q2 - r2 = 2*r2 + 1 - d; // update r2 - } - else { - if (q2 >= 0x8000000000000000ull) magu.a = 1; - q2 = 2*q2; // update q2 - r2 = 2*r2 + 1; // update r2 - } - delta = d - 1 - r2; - } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0))); - magu.m = q2 + 1; // resulting magic number - magu.s = p - 64; // resulting shift - return magu; -} - -/// BuildSDIVSequence - Given an ISD::SDIV node expressing a divide by constant, -/// return a DAG expression to select that will generate the same value by -/// multiplying by a magic number. See: -/// -SDOperand AlphaISel::BuildSDIVSequence(SDOperand N) { - int64_t d = (int64_t)cast(N.getOperand(1))->getSignExtended(); - ms magics = magic(d); - // Multiply the numerator (operand 0) by the magic value - SDOperand Q = ISelDAG->getNode(ISD::MULHS, MVT::i64, N.getOperand(0), - ISelDAG->getConstant(magics.m, MVT::i64)); - // If d > 0 and m < 0, add the numerator - if (d > 0 && magics.m < 0) - Q = ISelDAG->getNode(ISD::ADD, MVT::i64, Q, N.getOperand(0)); - // If d < 0 and m > 0, subtract the numerator. - if (d < 0 && magics.m > 0) - Q = ISelDAG->getNode(ISD::SUB, MVT::i64, Q, N.getOperand(0)); - // Shift right algebraic if shift value is nonzero - if (magics.s > 0) - Q = ISelDAG->getNode(ISD::SRA, MVT::i64, Q, - ISelDAG->getConstant(magics.s, MVT::i64)); - // Extract the sign bit and add it to the quotient - SDOperand T = - ISelDAG->getNode(ISD::SRL, MVT::i64, Q, ISelDAG->getConstant(63, MVT::i64)); - return ISelDAG->getNode(ISD::ADD, MVT::i64, Q, T); -} - -/// BuildUDIVSequence - Given an ISD::UDIV node expressing a divide by constant, -/// return a DAG expression to select that will generate the same value by -/// multiplying by a magic number. See: -/// -SDOperand AlphaISel::BuildUDIVSequence(SDOperand N) { - unsigned d = - (unsigned)cast(N.getOperand(1))->getSignExtended(); - mu magics = magicu(d); - // Multiply the numerator (operand 0) by the magic value - SDOperand Q = ISelDAG->getNode(ISD::MULHU, MVT::i64, N.getOperand(0), - ISelDAG->getConstant(magics.m, MVT::i64)); - if (magics.a == 0) { - Q = ISelDAG->getNode(ISD::SRL, MVT::i64, Q, - ISelDAG->getConstant(magics.s, MVT::i64)); - } else { - SDOperand NPQ = ISelDAG->getNode(ISD::SUB, MVT::i64, N.getOperand(0), Q); - NPQ = ISelDAG->getNode(ISD::SRL, MVT::i64, NPQ, - ISelDAG->getConstant(1, MVT::i64)); - NPQ = ISelDAG->getNode(ISD::ADD, MVT::i64, NPQ, Q); - Q = ISelDAG->getNode(ISD::SRL, MVT::i64, NPQ, - ISelDAG->getConstant(magics.s-1, MVT::i64)); - } - return Q; -} - //These describe LDAx static const int IMM_LOW = -32768; static const int IMM_HIGH = 32767; @@ -511,7 +369,7 @@ //assert(0 && "Setcc On float?\n"); std::cerr << "Setcc on float!\n"; Tmp3 = MakeReg(MVT::f64); - BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Alpha::F31).addReg(Tmp1); + BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp1); Tmp1 = Tmp3; } if (SetCC->getOperand(1).getValueType() == MVT::f32) @@ -519,7 +377,7 @@ //assert (0 && "Setcc On float?\n"); std::cerr << "Setcc on float!\n"; Tmp3 = MakeReg(MVT::f64); - BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Alpha::F31).addReg(Tmp2); + BuildMI(BB, Alpha::CVTST, 1, Tmp3).addReg(Tmp2); Tmp2 = Tmp3; } @@ -652,7 +510,7 @@ unsigned Tmp1, Tmp2 = 0, Tmp3; unsigned Opc = 0; unsigned opcode = N.getOpcode(); - int64_t SImm; + int64_t SImm = 0; uint64_t UImm; SDNode *Node = N.Val; @@ -691,13 +549,23 @@ Node->dump(); assert(0 && "Node not handled!\n"); + case ISD::READCYCLECOUNTER: + Select(N.getOperand(0)); //Select chain + if (Result != notIn) + ExprMap[N.getValue(1)] = notIn; // Generate the token + else + Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); + + BuildMI(BB, Alpha::RPCC, 1, Result).addReg(Alpha::R31); + return Result; + case ISD::CTPOP: case ISD::CTTZ: case ISD::CTLZ: Opc = opcode == ISD::CTPOP ? Alpha::CTPOP : (opcode == ISD::CTTZ ? Alpha::CTTZ : Alpha::CTLZ); Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, Opc, 1, Result).addReg(Alpha::R31).addReg(Tmp1); + BuildMI(BB, Opc, 1, Result).addReg(Tmp1); return Result; case ISD::MULHU: @@ -928,8 +796,11 @@ .addReg(argvregs[i]); break; case MVT::f32: + BuildMI(BB, Alpha::CPYSS, 2, args_float[i]).addReg(argvregs[i]) + .addReg(argvregs[i]); + break; case MVT::f64: - BuildMI(BB, Alpha::CPYS, 2, args_float[i]).addReg(argvregs[i]) + BuildMI(BB, Alpha::CPYST, 2, args_float[i]).addReg(argvregs[i]) .addReg(argvregs[i]); break; } @@ -985,8 +856,10 @@ BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0); break; case MVT::f32: - case MVT::f64: - BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F0).addReg(Alpha::F0); + BuildMI(BB, Alpha::CPYSS, 2, Result).addReg(Alpha::F0).addReg(Alpha::F0); + break; + case MVT::f64: + BuildMI(BB, Alpha::CPYST, 2, Result).addReg(Alpha::F0).addReg(Alpha::F0); break; } return Result+N.ResNo; @@ -1084,10 +957,10 @@ break; } case MVT::i16: - BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Alpha::R31).addReg(Tmp1); + BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1); break; case MVT::i8: - BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Alpha::R31).addReg(Tmp1); + BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1); break; case MVT::i1: Tmp2 = MakeReg(MVT::i64); @@ -1181,10 +1054,17 @@ Select(Chain); unsigned r = cast(Node->getOperand(1))->getReg(); //std::cerr << "CopyFromReg " << Result << " = " << r << "\n"; - if (MVT::isFloatingPoint(N.getValue(0).getValueType())) - BuildMI(BB, Alpha::CPYS, 2, Result).addReg(r).addReg(r); - else + switch(N.getValue(0).getValueType()) { + case MVT::f32: + BuildMI(BB, Alpha::CPYSS, 2, Result).addReg(r).addReg(r); + break; + case MVT::f64: + BuildMI(BB, Alpha::CPYST, 2, Result).addReg(r).addReg(r); + break; + default: BuildMI(BB, Alpha::BIS, 2, Result).addReg(r).addReg(r); + break; + } return Result; } @@ -1390,20 +1270,7 @@ } } //Else fall through - case ISD::UDIV: - { - if (isSIntImmediate(N.getOperand(1), SImm) && (SImm >= 2 || SImm <= -2)) - { - // If this is a divide by constant, we can emit code using some magic - // constants to implement it as a multiply instead. - ExprMap.erase(N); - if (opcode == ISD::SDIV) - return SelectExpr(BuildSDIVSequence(N)); - else - return SelectExpr(BuildUDIVSequence(N)); - } - } //else fall though case ISD::UREM: case ISD::SREM: { @@ -1438,11 +1305,11 @@ if (SrcType == MVT::f32) { Tmp2 = MakeReg(MVT::f64); - BuildMI(BB, Alpha::CVTST, 1, Tmp2).addReg(Alpha::F31).addReg(Tmp1); + BuildMI(BB, Alpha::CVTST, 1, Tmp2).addReg(Tmp1); Tmp1 = Tmp2; } Tmp2 = MakeReg(MVT::f64); - BuildMI(BB, Alpha::CVTTQ, 1, Tmp2).addReg(Alpha::F31).addReg(Tmp1); + BuildMI(BB, Alpha::CVTTQ, 1, Tmp2).addReg(Tmp1); MoveFP2Int(Tmp2, Result, true); return Result; @@ -1643,16 +1510,19 @@ if(ISD::FABS == N.getOperand(0).getOpcode()) { Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Alpha::F31).addReg(Tmp1); + BuildMI(BB, DestType == MVT::f64 ? Alpha::CPYSNT : Alpha::CPYSNS, + 2, Result).addReg(Alpha::F31).addReg(Tmp1); } else { Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Tmp1).addReg(Tmp1); + BuildMI(BB, DestType == MVT::f64 ? Alpha::CPYSNT : Alpha::CPYSNS + , 2, Result).addReg(Tmp1).addReg(Tmp1); } return Result; case ISD::FABS: Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F31).addReg(Tmp1); + BuildMI(BB, DestType == MVT::f64 ? Alpha::CPYST : Alpha::CPYSS, 2, Result) + .addReg(Alpha::F31).addReg(Tmp1); return Result; case ISD::FP_ROUND: @@ -1660,7 +1530,7 @@ N.getOperand(0).getValueType() == MVT::f64 && "only f64 to f32 conversion supported here"); Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, Alpha::CVTTS, 1, Result).addReg(Alpha::F31).addReg(Tmp1); + BuildMI(BB, Alpha::CVTTS, 1, Result).addReg(Tmp1); return Result; case ISD::FP_EXTEND: @@ -1668,16 +1538,18 @@ N.getOperand(0).getValueType() == MVT::f32 && "only f32 to f64 conversion supported here"); Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Alpha::F31).addReg(Tmp1); + BuildMI(BB, Alpha::CVTST, 1, Result).addReg(Tmp1); return Result; case ISD::ConstantFP: if (ConstantFPSDNode *CN = dyn_cast(N)) { if (CN->isExactlyValue(+0.0)) { - BuildMI(BB, Alpha::CPYS, 2, Result).addReg(Alpha::F31) + BuildMI(BB, DestType == MVT::f64 ? Alpha::CPYST : Alpha::CPYSS + , 2, Result).addReg(Alpha::F31) .addReg(Alpha::F31); } else if ( CN->isExactlyValue(-0.0)) { - BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Alpha::F31) + BuildMI(BB, DestType == MVT::f64 ? Alpha::CPYSNT : Alpha::CPYSNS, + 2, Result).addReg(Alpha::F31) .addReg(Alpha::F31); } else { abort(); @@ -1693,7 +1565,7 @@ Tmp2 = MakeReg(MVT::f64); MoveInt2FP(Tmp1, Tmp2, true); Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS; - BuildMI(BB, Opc, 1, Result).addReg(Alpha::F31).addReg(Tmp2); + BuildMI(BB, Opc, 1, Result).addReg(Tmp2); return Result; } @@ -1760,11 +1632,17 @@ Tmp2 = cast(N.getOperand(1))->getReg(); if (Tmp1 != Tmp2) { - if (N.getOperand(2).getValueType() == MVT::f64 || - N.getOperand(2).getValueType() == MVT::f32) - BuildMI(BB, Alpha::CPYS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1); - else + switch(N.getOperand(2).getValueType()) { + case MVT::f64: + BuildMI(BB, Alpha::CPYST, 2, Tmp2).addReg(Tmp1).addReg(Tmp1); + break; + case MVT::f32: + BuildMI(BB, Alpha::CPYSS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1); + break; + default: BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1); + break; + } } return; @@ -1784,8 +1662,10 @@ default: Node->dump(); assert(0 && "All other types should have been promoted!!"); case MVT::f64: + BuildMI(BB, Alpha::CPYST, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1); + break; case MVT::f32: - BuildMI(BB, Alpha::CPYS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1); + BuildMI(BB, Alpha::CPYSS, 2, Alpha::F0).addReg(Tmp1).addReg(Tmp1); break; case MVT::i32: case MVT::i64: @@ -1869,6 +1749,7 @@ case ISD::CopyFromReg: case ISD::TAILCALL: case ISD::CALL: + case ISD::READCYCLECOUNTER: case ISD::DYNAMIC_STACKALLOC: ExprMap.erase(N); SelectExpr(N); Index: llvm/lib/Target/Alpha/AlphaInstrFormats.td diff -u llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.6 llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.6.2.1 --- llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.6 Thu Jul 28 13:14:47 2005 +++ llvm/lib/Target/Alpha/AlphaInstrFormats.td Wed Nov 16 12:32:33 2005 @@ -17,26 +17,28 @@ //Floating-point //PALcode -def u8imm : Operand; -def s14imm : Operand; -def s16imm : Operand; -def s21imm : Operand; +def u8imm : Operand; +def s14imm : Operand; +def s16imm : Operand; +def s21imm : Operand; def s64imm : Operand; //===----------------------------------------------------------------------===// // Instruction format superclass //===----------------------------------------------------------------------===// - -class InstAlpha op, dag OL, string asmstr> : Instruction { // Alpha instruction baseline +// Alpha instruction baseline +class InstAlphaAlt op, string asmstr> : Instruction { field bits<32> Inst; let Namespace = "Alpha"; - let OperandList = OL; let AsmString = asmstr; - - let Inst{31-26} = op; } +class InstAlpha op, dag OL, string asmstr> +: InstAlphaAlt { // Alpha instruction baseline + let OperandList = OL; +} + //3.3.1 class MForm opcode, string asmstr> : InstAlpha { @@ -48,6 +50,15 @@ let Inst{20-16} = Rb; let Inst{15-0} = disp; } +class MfcForm opcode, bits<16> fc, string asmstr> + : InstAlpha { + bits<5> Ra; + bits<5> Rb; + + let Inst{25-21} = Ra; + let Inst{20-16} = Rb; + let Inst{15-0} = fc; +} class MgForm opcode, string asmstr> : InstAlpha { @@ -81,10 +92,18 @@ let Inst{25-21} = Ra; let Inst{20-0} = disp; } +class BFormD opcode, string asmstr> + : InstAlpha { + bits<5> Ra = 31; + bits<21> disp; + + let Inst{25-21} = Ra; + let Inst{20-0} = disp; +} let isBranch = 1, isTerminator = 1 in class FBForm opcode, string asmstr> - : InstAlpha { + : InstAlpha { bits<5> Ra; bits<21> disp; @@ -93,8 +112,10 @@ } //3.3.3 -class OForm opcode, bits<7> fun, string asmstr> +class OForm opcode, bits<7> fun, string asmstr, list pattern> : InstAlpha { + let Pattern = pattern; + bits<5> Rc; bits<5> Ra; bits<5> Rb; @@ -108,13 +129,30 @@ let Inst{4-0} = Rc; } -class OcmForm opcode, bits<7> fun, dag OL, string asmstr> - : InstAlpha { - bits<5> Ra; +class OForm2 opcode, bits<7> fun, string asmstr, list pattern> + : InstAlpha { + let Pattern = pattern; + + bits<5> Rc; bits<5> Rb; bits<7> Function = fun; + + let Inst{25-21} = 31; + let Inst{20-16} = Rb; + let Inst{15-13} = 0; + let Inst{12} = 0; + let Inst{11-5} = Function; + let Inst{4-0} = Rc; +} + +class OForm4 opcode, bits<7> fun, string asmstr> + : InstAlpha { bits<5> Rc; + bits<5> Rb; + bits<5> Ra; + bits<7> Function = fun; + let isTwoAddress = 1; let Inst{25-21} = Ra; let Inst{20-16} = Rb; let Inst{15-13} = 0; @@ -124,8 +162,10 @@ } -class OFormL opcode, bits<7> fun, string asmstr> +class OFormL opcode, bits<7> fun, string asmstr, list pattern> : InstAlpha { + let Pattern = pattern; + bits<5> Rc; bits<5> Ra; bits<8> LIT; @@ -138,13 +178,14 @@ let Inst{4-0} = Rc; } -class OcmFormL opcode, bits<7> fun, dag OL, string asmstr> - : InstAlpha { - bits<5> Ra; +class OForm4L opcode, bits<7> fun, string asmstr> + : InstAlpha { + bits<5> Rc; bits<8> LIT; + bits<5> Ra; bits<7> Function = fun; - bits<5> Rc; + let isTwoAddress = 1; let Inst{25-21} = Ra; let Inst{20-13} = LIT; let Inst{12} = 1; @@ -153,21 +194,10 @@ } //3.3.4 -class FPForm opcode, bits<11> fun, string asmstr> - : InstAlpha { - bits<5> Fc; - bits<5> Fa; - bits<5> Fb; - bits<11> Function = fun; - - let Inst{25-21} = Fa; - let Inst{20-16} = Fb; - let Inst{15-5} = Function; - let Inst{4-0} = Fc; -} +class FPForm opcode, bits<11> fun, string asmstr, list pattern> + : InstAlphaAlt { + let Pattern = pattern; -class FPFormCM opcode, bits<11> fun, dag OL, string asmstr> - : InstAlpha { bits<5> Fc; bits<5> Fa; bits<5> Fb; Index: llvm/lib/Target/Alpha/AlphaInstrInfo.cpp diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.5 llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.5.4.1 --- llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.5 Thu Apr 21 18:10:23 2005 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.cpp Wed Nov 16 12:32:33 2005 @@ -26,7 +26,9 @@ unsigned& sourceReg, unsigned& destReg) const { MachineOpCode oc = MI.getOpcode(); - if (oc == Alpha::BIS || oc == Alpha::CPYS) { // or r1, r2, r2 // cpys r1 r2 r2 + if (oc == Alpha::BIS || oc == Alpha::CPYSS || oc == Alpha::CPYST) { + // or r1, r2, r2 + // cpys(s|t) r1 r2 r2 assert(MI.getNumOperands() == 3 && MI.getOperand(0).isRegister() && MI.getOperand(1).isRegister() && Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.59 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.59.2.1 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.59 Thu Oct 6 11:53:32 2005 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Wed Nov 16 12:32:33 2005 @@ -12,6 +12,62 @@ include "AlphaInstrFormats.td" +//******************** +//Paterns for matching +//******************** + +def immUExt8 : PatLeaf<(imm), [{ + // immUExt8 predicate - True if the immediate fits in a 8-bit zero extended + // field. Used by instructions like 'addi'. + return (unsigned long)N->getValue() == (unsigned char)N->getValue(); +}]>; +def immSExt16 : PatLeaf<(imm), [{ + // immSExt16 predicate - True if the immediate fits in a 16-bit sign extended + // field. Used by instructions like 'lda'. + return (int)N->getValue() == (short)N->getValue(); +}]>; + +def iZAPX : SDNodeXFormgetValue(); + unsigned int build = 0; + for(int i = 0; i < 8; ++i) + { + if ((UImm & 0x00FF) == 0x00FF) + build |= 1 << i; + else if ((UImm & 0x00FF) != 0) + { build = 0; break; } + UImm >>= 8; + } + return getI64Imm(build); +}]>; +def immZAP : PatLeaf<(imm), [{ + // immZAP predicate - True if the immediate fits is suitable for use in a + // ZAP instruction + uint64_t UImm = (uint64_t)N->getValue(); + unsigned int build = 0; + for(int i = 0; i < 8; ++i) + { + if ((UImm & 0x00FF) == 0x00FF) + build |= 1 << i; + else if ((UImm & 0x00FF) != 0) + { build = 0; break; } + UImm >>= 8; + } + return build != 0; +}], iZAPX>; + + +def intop : PatFrag<(ops node:$op), (sext_inreg node:$op, i32)>; +def add4 : PatFrag<(ops node:$op1, node:$op2), + (add (shl node:$op1, 2), node:$op2)>; +def sub4 : PatFrag<(ops node:$op1, node:$op2), + (sub (shl node:$op1, 2), node:$op2)>; +def add8 : PatFrag<(ops node:$op1, node:$op2), + (add (shl node:$op1, 3), node:$op2)>; +def sub8 : PatFrag<(ops node:$op1, node:$op2), + (sub (shl node:$op1, 3), node:$op2)>; + // //#define FP $15 // //#define RA $26 // //#define PV $27 @@ -40,19 +96,19 @@ //really the ISel should emit multiple MBB let isTwoAddress = 1 in { //Conditional move of an int based on a FP CC - def CMOVEQ_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, FPRC:$RCOND), + def CMOVEQ_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND), "fbne $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n">; - def CMOVEQi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, FPRC:$RCOND), + def CMOVEQi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, F8RC:$RCOND), "fbne $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n">; - def CMOVNE_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, FPRC:$RCOND), + def CMOVNE_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND), "fbeq $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n">; - def CMOVNEi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, FPRC:$RCOND), + def CMOVNEi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, F8RC:$RCOND), "fbeq $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n">; //Conditional move of an FP based on a Int CC - def FCMOVEQ_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, FPRC:$RCOND), + def FCMOVEQ_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND), "bne $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n">; - def FCMOVNE_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, FPRC:$RCOND), + def FCMOVNE_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND), "beq $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n">; } @@ -62,200 +118,250 @@ //Operation Form: -let isTwoAddress = 1 in { //conditional moves, int - def CMOVEQ : OcmForm< 0x11, 0x24, (ops GPRC:$RDEST, GPRC:$RSRC2, GPRC:$RSRC, GPRC:$RCOND), - "cmoveq $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND = zero - def CMOVEQi : OcmFormL< 0x11, 0x24, (ops GPRC:$RDEST, GPRC:$RSRC2, u8imm:$L, GPRC:$RCOND), - "cmoveq $RCOND,$L,$RDEST">; //CMOVE if RCOND = zero - def CMOVGE : OcmForm< 0x11, 0x46, (ops GPRC:$RDEST, GPRC:$RSRC2, GPRC:$RSRC, GPRC:$RCOND), - "cmovge $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND >= zero - def CMOVGEi : OcmFormL< 0x11, 0x46, (ops GPRC:$RDEST, GPRC:$RSRC2, u8imm:$L, GPRC:$RCOND), - "cmovge $RCOND,$L,$RDEST">; //CMOVE if RCOND >= zero - def CMOVGT : OcmForm< 0x11, 0x66, (ops GPRC:$RDEST, GPRC:$RSRC2, GPRC:$RSRC, GPRC:$RCOND), - "cmovgt $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND > zero - def CMOVGTi : OcmFormL< 0x11, 0x66, (ops GPRC:$RDEST, GPRC:$RSRC2, u8imm:$L, GPRC:$RCOND), - "cmovgt $RCOND,$L,$RDEST">; //CMOVE if RCOND > zero - def CMOVLBC : OcmForm< 0x11, 0x16, (ops GPRC:$RDEST, GPRC:$RSRC2, GPRC:$RSRC, GPRC:$RCOND), - "cmovlbc $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND low bit clear - def CMOVLBCi : OcmFormL< 0x11, 0x16, (ops GPRC:$RDEST, GPRC:$RSRC2, u8imm:$L, GPRC:$RCOND), - "cmovlbc $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit clear - def CMOVLBS : OcmForm< 0x11, 0x14, (ops GPRC:$RDEST, GPRC:$RSRC2, GPRC:$RSRC, GPRC:$RCOND), - "cmovlbs $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND low bit set - def CMOVLBSi : OcmFormL< 0x11, 0x14, (ops GPRC:$RDEST, GPRC:$RSRC2, u8imm:$L, GPRC:$RCOND), - "cmovlbs $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit set - def CMOVLE : OcmForm< 0x11, 0x64, (ops GPRC:$RDEST, GPRC:$RSRC2, GPRC:$RSRC, GPRC:$RCOND), - "cmovle $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND <= zero - def CMOVLEi : OcmFormL< 0x11, 0x64, (ops GPRC:$RDEST, GPRC:$RSRC2, u8imm:$L, GPRC:$RCOND), - "cmovle $RCOND,$L,$RDEST">; //CMOVE if RCOND <= zero - def CMOVLT : OcmForm< 0x11, 0x44, (ops GPRC:$RDEST, GPRC:$RSRC2, GPRC:$RSRC, GPRC:$RCOND), - "cmovlt $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND < zero - def CMOVLTi : OcmFormL< 0x11, 0x44, (ops GPRC:$RDEST, GPRC:$RSRC2, u8imm:$L, GPRC:$RCOND), - "cmovlt $RCOND,$L,$RDEST">; //CMOVE if RCOND < zero - def CMOVNE : OcmForm< 0x11, 0x26, (ops GPRC:$RDEST, GPRC:$RSRC2, GPRC:$RSRC, GPRC:$RCOND), - "cmovne $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND != zero - def CMOVNEi : OcmFormL< 0x11, 0x26, (ops GPRC:$RDEST, GPRC:$RSRC2, u8imm:$L, GPRC:$RCOND), - "cmovne $RCOND,$L,$RDEST">; //CMOVE if RCOND != zero +def CMOVEQ : OForm4< 0x11, 0x24, "cmoveq $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND = zero +def CMOVEQi : OForm4L< 0x11, 0x24, "cmoveq $RCOND,$L,$RDEST">; //CMOVE if RCOND = zero +def CMOVGE : OForm4< 0x11, 0x46, "cmovge $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND >= zero +def CMOVGEi : OForm4L< 0x11, 0x46, "cmovge $RCOND,$L,$RDEST">; //CMOVE if RCOND >= zero +def CMOVGT : OForm4< 0x11, 0x66, "cmovgt $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND > zero +def CMOVGTi : OForm4L< 0x11, 0x66, "cmovgt $RCOND,$L,$RDEST">; //CMOVE if RCOND > zero +def CMOVLBC : OForm4< 0x11, 0x16, "cmovlbc $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND low bit clear +def CMOVLBCi : OForm4L< 0x11, 0x16, "cmovlbc $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit clear +def CMOVLBS : OForm4< 0x11, 0x14, "cmovlbs $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND low bit set +def CMOVLBSi : OForm4L< 0x11, 0x14, "cmovlbs $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit set +def CMOVLE : OForm4< 0x11, 0x64, "cmovle $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND <= zero +def CMOVLEi : OForm4L< 0x11, 0x64, "cmovle $RCOND,$L,$RDEST">; //CMOVE if RCOND <= zero +def CMOVLT : OForm4< 0x11, 0x44, "cmovlt $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND < zero +def CMOVLTi : OForm4L< 0x11, 0x44, "cmovlt $RCOND,$L,$RDEST">; //CMOVE if RCOND < zero +def CMOVNE : OForm4< 0x11, 0x26, "cmovne $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND != zero +def CMOVNEi : OForm4L< 0x11, 0x26, "cmovne $RCOND,$L,$RDEST">; //CMOVE if RCOND != zero //conditional moves, fp - def FCMOVEQ : FPFormCM<0x17, 0x02A, (ops FPRC:$RDEST, FPRC:$RSRC2, FPRC:$RSRC, FPRC:$RCOND), - "fcmoveq $RCOND,$RSRC,$RDEST">; //FCMOVE if = zero - def FCMOVGE : FPFormCM<0x17, 0x02D, (ops FPRC:$RDEST, FPRC:$RSRC2, FPRC:$RSRC, FPRC:$RCOND), - "fcmovge $RCOND,$RSRC,$RDEST">; //FCMOVE if >= zero - def FCMOVGT : FPFormCM<0x17, 0x02F, (ops FPRC:$RDEST, FPRC:$RSRC2, FPRC:$RSRC, FPRC:$RCOND), - "fcmovgt $RCOND,$RSRC,$RDEST">; //FCMOVE if > zero - def FCMOVLE : FPFormCM<0x17, 0x02E, (ops FPRC:$RDEST, FPRC:$RSRC2, FPRC:$RSRC, FPRC:$RCOND), - "fcmovle $RCOND,$RSRC,$RDEST">; //FCMOVE if <= zero - def FCMOVLT : FPFormCM<0x17, 0x02, (ops FPRC:$RDEST, FPRC:$RSRC2, FPRC:$RSRC, FPRC:$RCOND), - "fcmovlt $RCOND,$RSRC,$RDEST">; // FCMOVE if < zero - def FCMOVNE : FPFormCM<0x17, 0x02B, (ops FPRC:$RDEST, FPRC:$RSRC2, FPRC:$RSRC, FPRC:$RCOND), - "fcmovne $RCOND,$RSRC,$RDEST">; //FCMOVE if != zero +let OperandList = (ops F8RC:$RDEST, F8RC:$RSRC2, F8RC:$RSRC, F8RC:$RCOND), + isTwoAddress = 1 in { +def FCMOVEQ : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if = zero +def FCMOVGE : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if >= zero +def FCMOVGT : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if > zero +def FCMOVLE : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if <= zero +def FCMOVLT : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RSRC,$RDEST",[]>; // FCMOVE if < zero +def FCMOVNE : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if != zero } -def ADDL : OForm< 0x10, 0x00, "addl $RA,$RB,$RC">; //Add longword -def ADDLi : OFormL<0x10, 0x00, "addl $RA,$L,$RC">; //Add longword -def ADDQ : OForm< 0x10, 0x20, "addq $RA,$RB,$RC">; //Add quadword -def ADDQi : OFormL<0x10, 0x20, "addq $RA,$L,$RC">; //Add quadword -def AMASK : OForm< 0x11, 0x61, "AMASK $RA,$RB,$RC">; //Architecture mask -def AMASKi : OFormL<0x11, 0x61, "AMASK $RA,$L,$RC">; //Architecture mask -def AND : OForm< 0x11, 0x00, "and $RA,$RB,$RC">; //Logical product -def ANDi : OFormL<0x11, 0x00, "and $RA,$L,$RC">; //Logical product -def BIC : OForm< 0x11, 0x08, "bic $RA,$RB,$RC">; //Bit clear -def BICi : OFormL<0x11, 0x08, "bic $RA,$L,$RC">; //Bit clear -def BIS : OForm< 0x11, 0x20, "bis $RA,$RB,$RC">; //Logical sum -def BISi : OFormL<0x11, 0x20, "bis $RA,$L,$RC">; //Logical sum -def CTLZ : OForm< 0x1C, 0x32, "CTLZ $RB,$RC">; //Count leading zero -def CTPOP : OForm< 0x1C, 0x30, "CTPOP $RB,$RC">; //Count population -def CTTZ : OForm< 0x1C, 0x33, "CTTZ $RB,$RC">; //Count trailing zero -def EQV : OForm< 0x11, 0x48, "eqv $RA,$RB,$RC">; //Logical equivalence -def EQVi : OFormL<0x11, 0x48, "eqv $RA,$L,$RC">; //Logical equivalence -def EXTBL : OForm< 0x12, 0x06, "EXTBL $RA,$RB,$RC">; //Extract byte low -def EXTBLi : OFormL<0x12, 0x06, "EXTBL $RA,$L,$RC">; //Extract byte low -def EXTLH : OForm< 0x12, 0x6A, "EXTLH $RA,$RB,$RC">; //Extract longword high -def EXTLHi : OFormL<0x12, 0x6A, "EXTLH $RA,$L,$RC">; //Extract longword high -def EXTLL : OForm< 0x12, 0x26, "EXTLL $RA,$RB,$RC">; //Extract longword low -def EXTLLi : OFormL<0x12, 0x26, "EXTLL $RA,$L,$RC">; //Extract longword low -def EXTQH : OForm< 0x12, 0x7A, "EXTQH $RA,$RB,$RC">; //Extract quadword high -def EXTQHi : OFormL<0x12, 0x7A, "EXTQH $RA,$L,$RC">; //Extract quadword high -def EXTQ : OForm< 0x12, 0x36, "EXTQ $RA,$RB,$RC">; //Extract quadword low -def EXTQi : OFormL<0x12, 0x36, "EXTQ $RA,$L,$RC">; //Extract quadword low -def EXTWH : OForm< 0x12, 0x5A, "EXTWH $RA,$RB,$RC">; //Extract word high -def EXTWHi : OFormL<0x12, 0x5A, "EXTWH $RA,$L,$RC">; //Extract word high -def EXTWL : OForm< 0x12, 0x16, "EXTWL $RA,$RB,$RC">; //Extract word low -def EXTWLi : OFormL<0x12, 0x16, "EXTWL $RA,$L,$RC">; //Extract word low -def IMPLVER : OForm< 0x11, 0x6C, "IMPLVER $RA,$RB,$RC">; //Implementation version -def IMPLVERi : OFormL<0x11, 0x6C, "IMPLVER $RA,$L,$RC">; //Implementation version -def INSBL : OForm< 0x12, 0x0B, "INSBL $RA,$RB,$RC">; //Insert byte low -def INSBLi : OFormL<0x12, 0x0B, "INSBL $RA,$L,$RC">; //Insert byte low -def INSLH : OForm< 0x12, 0x67, "INSLH $RA,$RB,$RC">; //Insert longword high -def INSLHi : OFormL<0x12, 0x67, "INSLH $RA,$L,$RC">; //Insert longword high -def INSLL : OForm< 0x12, 0x2B, "INSLL $RA,$RB,$RC">; //Insert longword low -def INSLLi : OFormL<0x12, 0x2B, "INSLL $RA,$L,$RC">; //Insert longword low -def INSQH : OForm< 0x12, 0x77, "INSQH $RA,$RB,$RC">; //Insert quadword high -def INSQHi : OFormL<0x12, 0x77, "INSQH $RA,$L,$RC">; //Insert quadword high -def INSQL : OForm< 0x12, 0x3B, "INSQL $RA,$RB,$RC">; //Insert quadword low -def INSQLi : OFormL<0x12, 0x3B, "INSQL $RA,$L,$RC">; //Insert quadword low -def INSWH : OForm< 0x12, 0x57, "INSWH $RA,$RB,$RC">; //Insert word high -def INSWHi : OFormL<0x12, 0x57, "INSWH $RA,$L,$RC">; //Insert word high -def INSWL : OForm< 0x12, 0x1B, "INSWL $RA,$RB,$RC">; //Insert word low -def INSWLi : OFormL<0x12, 0x1B, "INSWL $RA,$L,$RC">; //Insert word low -def MSKBL : OForm< 0x12, 0x02, "MSKBL $RA,$RB,$RC">; //Mask byte low -def MSKBLi : OFormL<0x12, 0x02, "MSKBL $RA,$L,$RC">; //Mask byte low -def MSKLH : OForm< 0x12, 0x62, "MSKLH $RA,$RB,$RC">; //Mask longword high -def MSKLHi : OFormL<0x12, 0x62, "MSKLH $RA,$L,$RC">; //Mask longword high -def MSKLL : OForm< 0x12, 0x22, "MSKLL $RA,$RB,$RC">; //Mask longword low -def MSKLLi : OFormL<0x12, 0x22, "MSKLL $RA,$L,$RC">; //Mask longword low -def MSKQH : OForm< 0x12, 0x72, "MSKQH $RA,$RB,$RC">; //Mask quadword high -def MSKQHi : OFormL<0x12, 0x72, "MSKQH $RA,$L,$RC">; //Mask quadword high -def MSKQL : OForm< 0x12, 0x32, "MSKQL $RA,$RB,$RC">; //Mask quadword low -def MSKQLi : OFormL<0x12, 0x32, "MSKQL $RA,$L,$RC">; //Mask quadword low -def MSKWH : OForm< 0x12, 0x52, "MSKWH $RA,$RB,$RC">; //Mask word high -def MSKWHi : OFormL<0x12, 0x52, "MSKWH $RA,$L,$RC">; //Mask word high -def MSKWL : OForm< 0x12, 0x12, "MSKWL $RA,$RB,$RC">; //Mask word low -def MSKWLi : OFormL<0x12, 0x12, "MSKWL $RA,$L,$RC">; //Mask word low -def MULL : OForm< 0x13, 0x00, "mull $RA,$RB,$RC">; //Multiply longword -def MULLi : OFormL<0x13, 0x00, "mull $RA,$L,$RC">; //Multiply longword -def MULQ : OForm< 0x13, 0x20, "mulq $RA,$RB,$RC">; //Multiply quadword -def MULQi : OFormL<0x13, 0x20, "mulq $RA,$L,$RC">; //Multiply quadword -def ORNOT : OForm< 0x11, 0x28, "ornot $RA,$RB,$RC">; //Logical sum with complement -def ORNOTi : OFormL<0x11, 0x28, "ornot $RA,$L,$RC">; //Logical sum with complement -def S4ADDL : OForm< 0x10, 0x02, "s4addl $RA,$RB,$RC">; //Scaled add longword by 4 -def S4ADDLi : OFormL<0x10, 0x02, "s4addl $RA,$L,$RC">; //Scaled add longword by 4 -def S4ADDQ : OForm< 0x10, 0x22, "s4addq $RA,$RB,$RC">; //Scaled add quadword by 4 -def S4ADDQi : OFormL<0x10, 0x22, "s4addq $RA,$L,$RC">; //Scaled add quadword by 4 -def S4SUBL : OForm< 0x10, 0x0B, "s4subl $RA,$RB,$RC">; //Scaled subtract longword by 4 -def S4SUBLi : OFormL<0x10, 0x0B, "s4subl $RA,$L,$RC">; //Scaled subtract longword by 4 -def S4SUBQ : OForm< 0x10, 0x2B, "s4subq $RA,$RB,$RC">; //Scaled subtract quadword by 4 -def S4SUBQi : OFormL<0x10, 0x2B, "s4subq $RA,$L,$RC">; //Scaled subtract quadword by 4 -def S8ADDL : OForm< 0x10, 0x12, "s8addl $RA,$RB,$RC">; //Scaled add longword by 8 -def S8ADDLi : OFormL<0x10, 0x12, "s8addl $RA,$L,$RC">; //Scaled add longword by 8 -def S8ADDQ : OForm< 0x10, 0x32, "s8addq $RA,$RB,$RC">; //Scaled add quadword by 8 -def S8ADDQi : OFormL<0x10, 0x32, "s8addq $RA,$L,$RC">; //Scaled add quadword by 8 -def S8SUBL : OForm< 0x10, 0x1B, "s8subl $RA,$RB,$RC">; //Scaled subtract longword by 8 -def S8SUBLi : OFormL<0x10, 0x1B, "s8subl $RA,$L,$RC">; //Scaled subtract longword by 8 -def S8SUBQ : OForm< 0x10, 0x3B, "s8subq $RA,$RB,$RC">; //Scaled subtract quadword by 8 -def S8SUBQi : OFormL<0x10, 0x3B, "s8subq $RA,$L,$RC">; //Scaled subtract quadword by 8 -def SEXTB : OForm< 0x1C, 0x00, "sextb $RB,$RC">; //Sign extend byte -def SEXTW : OForm< 0x1C, 0x01, "sextw $RB,$RC">; //Sign extend word -def SL : OForm< 0x12, 0x39, "sll $RA,$RB,$RC">; //Shift left logical -def SLi : OFormL<0x12, 0x39, "sll $RA,$L,$RC">; //Shift left logical -def SRA : OForm< 0x12, 0x3C, "sra $RA,$RB,$RC">; //Shift right arithmetic -def SRAi : OFormL<0x12, 0x3C, "sra $RA,$L,$RC">; //Shift right arithmetic -def SRL : OForm< 0x12, 0x34, "srl $RA,$RB,$RC">; //Shift right logical - -def SRLi : OFormL<0x12, 0x34, "srl $RA,$L,$RC">; //Shift right logical -def SUBL : OForm< 0x10, 0x09, "subl $RA,$RB,$RC">; //Subtract longword -def SUBLi : OFormL<0x10, 0x09, "subl $RA,$L,$RC">; //Subtract longword -def SUBQ : OForm< 0x10, 0x29, "subq $RA,$RB,$RC">; //Subtract quadword -def SUBQi : OFormL<0x10, 0x29, "subq $RA,$L,$RC">; //Subtract quadword -def UMULH : OForm< 0x13, 0x30, "umulh $RA,$RB,$RC">; //Unsigned multiply quadword high -def UMULHi : OFormL<0x13, 0x30, "umulh $RA,$L,$RC">; //Unsigned multiply quadword high -def XOR : OForm< 0x11, 0x40, "xor $RA,$RB,$RC">; //Logical difference -def XORi : OFormL<0x11, 0x40, "xor $RA,$L,$RC">; //Logical difference -def ZAP : OForm< 0x12, 0x30, "zap $RA,$RB,$RC">; //Zero bytes -def ZAPi : OFormL<0x12, 0x30, "zap $RA,$L,$RC">; //Zero bytes -def ZAPNOT : OForm< 0x12, 0x31, "zapnot $RA,$RB,$RC">; //Zero bytes not -def ZAPNOTi : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC">; //Zero bytes not +def ADDL : OForm< 0x10, 0x00, "addl $RA,$RB,$RC", + [(set GPRC:$RC, (intop (add GPRC:$RA, GPRC:$RB)))]>; +def ADDLi : OFormL<0x10, 0x00, "addl $RA,$L,$RC", + [(set GPRC:$RC, (intop (add GPRC:$RA, immUExt8:$L)))]>; +def ADDQ : OForm< 0x10, 0x20, "addq $RA,$RB,$RC", + [(set GPRC:$RC, (add GPRC:$RA, GPRC:$RB))]>; +def ADDQi : OFormL<0x10, 0x20, "addq $RA,$L,$RC", + [(set GPRC:$RC, (add GPRC:$RA, immUExt8:$L))]>; +def AND : OForm< 0x11, 0x00, "and $RA,$RB,$RC", + [(set GPRC:$RC, (and GPRC:$RA, GPRC:$RB))]>; +def ANDi : OFormL<0x11, 0x00, "and $RA,$L,$RC", + [(set GPRC:$RC, (and GPRC:$RA, immUExt8:$L))]>; +def BIC : OForm< 0x11, 0x08, "bic $RA,$RB,$RC", + [(set GPRC:$RC, (and GPRC:$RA, (not GPRC:$RB)))]>; +def BICi : OFormL<0x11, 0x08, "bic $RA,$L,$RC", []>; +// [(set GPRC:$RC, (and GPRC:$RA, (not immUExt8:$L)))]>; //FIXME? +def BIS : OForm< 0x11, 0x20, "bis $RA,$RB,$RC", + [(set GPRC:$RC, (or GPRC:$RA, GPRC:$RB))]>; +def BISi : OFormL<0x11, 0x20, "bis $RA,$L,$RC", + [(set GPRC:$RC, (or GPRC:$RA, immUExt8:$L))]>; +def CTLZ : OForm2<0x1C, 0x32, "CTLZ $RB,$RC", + [(set GPRC:$RC, (ctlz GPRC:$RB))]>; +def CTPOP : OForm2<0x1C, 0x30, "CTPOP $RB,$RC", + [(set GPRC:$RC, (ctpop GPRC:$RB))]>; +def CTTZ : OForm2<0x1C, 0x33, "CTTZ $RB,$RC", + [(set GPRC:$RC, (cttz GPRC:$RB))]>; +def EQV : OForm< 0x11, 0x48, "eqv $RA,$RB,$RC", + [(set GPRC:$RC, (xor GPRC:$RA, (not GPRC:$RB)))]>; +def EQVi : OFormL<0x11, 0x48, "eqv $RA,$L,$RC", []>; +// [(set GPRC:$RC, (xor GPRC:$RA, (not immUExt8:$L)))]>; +//def EXTBL : OForm< 0x12, 0x06, "EXTBL $RA,$RB,$RC", []>; //Extract byte low +//def EXTBLi : OFormL<0x12, 0x06, "EXTBL $RA,$L,$RC", []>; //Extract byte low +//def EXTLH : OForm< 0x12, 0x6A, "EXTLH $RA,$RB,$RC", []>; //Extract longword high +//def EXTLHi : OFormL<0x12, 0x6A, "EXTLH $RA,$L,$RC", []>; //Extract longword high +//def EXTLL : OForm< 0x12, 0x26, "EXTLL $RA,$RB,$RC", []>; //Extract longword low +//def EXTLLi : OFormL<0x12, 0x26, "EXTLL $RA,$L,$RC", []>; //Extract longword low +//def EXTQH : OForm< 0x12, 0x7A, "EXTQH $RA,$RB,$RC", []>; //Extract quadword high +//def EXTQHi : OFormL<0x12, 0x7A, "EXTQH $RA,$L,$RC", []>; //Extract quadword high +//def EXTQ : OForm< 0x12, 0x36, "EXTQ $RA,$RB,$RC", []>; //Extract quadword low +//def EXTQi : OFormL<0x12, 0x36, "EXTQ $RA,$L,$RC", []>; //Extract quadword low +//def EXTWH : OForm< 0x12, 0x5A, "EXTWH $RA,$RB,$RC", []>; //Extract word high +//def EXTWHi : OFormL<0x12, 0x5A, "EXTWH $RA,$L,$RC", []>; //Extract word high +//def EXTWL : OForm< 0x12, 0x16, "EXTWL $RA,$RB,$RC", []>; //Extract word low +//def EXTWLi : OFormL<0x12, 0x16, "EXTWL $RA,$L,$RC", []>; //Extract word low +//def IMPLVER : OForm< 0x11, 0x6C, "IMPLVER $RA,$RB,$RC", []>; //Implementation version +//def IMPLVERi : OFormL<0x11, 0x6C, "IMPLVER $RA,$L,$RC", []>; //Implementation version +//def INSBL : OForm< 0x12, 0x0B, "INSBL $RA,$RB,$RC", []>; //Insert byte low +//def INSBLi : OFormL<0x12, 0x0B, "INSBL $RA,$L,$RC", []>; //Insert byte low +//def INSLH : OForm< 0x12, 0x67, "INSLH $RA,$RB,$RC", []>; //Insert longword high +//def INSLHi : OFormL<0x12, 0x67, "INSLH $RA,$L,$RC", []>; //Insert longword high +//def INSLL : OForm< 0x12, 0x2B, "INSLL $RA,$RB,$RC", []>; //Insert longword low +//def INSLLi : OFormL<0x12, 0x2B, "INSLL $RA,$L,$RC", []>; //Insert longword low +//def INSQH : OForm< 0x12, 0x77, "INSQH $RA,$RB,$RC", []>; //Insert quadword high +//def INSQHi : OFormL<0x12, 0x77, "INSQH $RA,$L,$RC", []>; //Insert quadword high +//def INSQL : OForm< 0x12, 0x3B, "INSQL $RA,$RB,$RC", []>; //Insert quadword low +//def INSQLi : OFormL<0x12, 0x3B, "INSQL $RA,$L,$RC", []>; //Insert quadword low +//def INSWH : OForm< 0x12, 0x57, "INSWH $RA,$RB,$RC", []>; //Insert word high +//def INSWHi : OFormL<0x12, 0x57, "INSWH $RA,$L,$RC", []>; //Insert word high +//def INSWL : OForm< 0x12, 0x1B, "INSWL $RA,$RB,$RC", []>; //Insert word low +//def INSWLi : OFormL<0x12, 0x1B, "INSWL $RA,$L,$RC", []>; //Insert word low +//def MSKBL : OForm< 0x12, 0x02, "MSKBL $RA,$RB,$RC", []>; //Mask byte low +//def MSKBLi : OFormL<0x12, 0x02, "MSKBL $RA,$L,$RC", []>; //Mask byte low +//def MSKLH : OForm< 0x12, 0x62, "MSKLH $RA,$RB,$RC", []>; //Mask longword high +//def MSKLHi : OFormL<0x12, 0x62, "MSKLH $RA,$L,$RC", []>; //Mask longword high +//def MSKLL : OForm< 0x12, 0x22, "MSKLL $RA,$RB,$RC", []>; //Mask longword low +//def MSKLLi : OFormL<0x12, 0x22, "MSKLL $RA,$L,$RC", []>; //Mask longword low +//def MSKQH : OForm< 0x12, 0x72, "MSKQH $RA,$RB,$RC", []>; //Mask quadword high +//def MSKQHi : OFormL<0x12, 0x72, "MSKQH $RA,$L,$RC", []>; //Mask quadword high +//def MSKQL : OForm< 0x12, 0x32, "MSKQL $RA,$RB,$RC", []>; //Mask quadword low +//def MSKQLi : OFormL<0x12, 0x32, "MSKQL $RA,$L,$RC", []>; //Mask quadword low +//def MSKWH : OForm< 0x12, 0x52, "MSKWH $RA,$RB,$RC", []>; //Mask word high +//def MSKWHi : OFormL<0x12, 0x52, "MSKWH $RA,$L,$RC", []>; //Mask word high +//def MSKWL : OForm< 0x12, 0x12, "MSKWL $RA,$RB,$RC", []>; //Mask word low +//def MSKWLi : OFormL<0x12, 0x12, "MSKWL $RA,$L,$RC", []>; //Mask word low + +def MULL : OForm< 0x13, 0x00, "mull $RA,$RB,$RC", + [(set GPRC:$RC, (intop (mul GPRC:$RA, GPRC:$RB)))]>; +def MULLi : OFormL<0x13, 0x00, "mull $RA,$L,$RC", + [(set GPRC:$RC, (intop (mul GPRC:$RA, immUExt8:$L)))]>; +def MULQ : OForm< 0x13, 0x20, "mulq $RA,$RB,$RC", + [(set GPRC:$RC, (mul GPRC:$RA, GPRC:$RB))]>; +def MULQi : OFormL<0x13, 0x20, "mulq $RA,$L,$RC", + [(set GPRC:$RC, (mul GPRC:$RA, immUExt8:$L))]>; +def ORNOT : OForm< 0x11, 0x28, "ornot $RA,$RB,$RC", + [(set GPRC:$RC, (or GPRC:$RA, (not GPRC:$RB)))]>; +def ORNOTi : OFormL<0x11, 0x28, "ornot $RA,$L,$RC", []>; +// [(set GPRC:$RC, (or GPRC:$RA, (not immUExt8:$L)))]>; +def S4ADDL : OForm< 0x10, 0x02, "s4addl $RA,$RB,$RC", + [(set GPRC:$RC, (intop (add4 GPRC:$RA, GPRC:$RB)))]>; +def S4ADDLi : OFormL<0x10, 0x02, "s4addl $RA,$L,$RC", + [(set GPRC:$RC, (intop (add4 GPRC:$RA, immUExt8:$L)))]>; +def S4ADDQ : OForm< 0x10, 0x22, "s4addq $RA,$RB,$RC", + [(set GPRC:$RC, (add4 GPRC:$RA, GPRC:$RB))]>; +def S4ADDQi : OFormL<0x10, 0x22, "s4addq $RA,$L,$RC", + [(set GPRC:$RC, (add4 GPRC:$RA, immUExt8:$L))]>; +def S4SUBL : OForm< 0x10, 0x0B, "s4subl $RA,$RB,$RC", + [(set GPRC:$RC, (intop (sub4 GPRC:$RA, GPRC:$RB)))]>; +def S4SUBLi : OFormL<0x10, 0x0B, "s4subl $RA,$L,$RC", + [(set GPRC:$RC, (intop (sub4 GPRC:$RA, immUExt8:$L)))]>; +def S4SUBQ : OForm< 0x10, 0x2B, "s4subq $RA,$RB,$RC", + [(set GPRC:$RC, (sub4 GPRC:$RA, GPRC:$RB))]>; +def S4SUBQi : OFormL<0x10, 0x2B, "s4subq $RA,$L,$RC", + [(set GPRC:$RC, (sub4 GPRC:$RA, immUExt8:$L))]>; +def S8ADDL : OForm< 0x10, 0x12, "s8addl $RA,$RB,$RC", + [(set GPRC:$RC, (intop (add8 GPRC:$RA, GPRC:$RB)))]>; +def S8ADDLi : OFormL<0x10, 0x12, "s8addl $RA,$L,$RC", + [(set GPRC:$RC, (intop (add8 GPRC:$RA, immUExt8:$L)))]>; +def S8ADDQ : OForm< 0x10, 0x32, "s8addq $RA,$RB,$RC", + [(set GPRC:$RC, (add8 GPRC:$RA, GPRC:$RB))]>; +def S8ADDQi : OFormL<0x10, 0x32, "s8addq $RA,$L,$RC", + [(set GPRC:$RC, (add8 GPRC:$RA, immUExt8:$L))]>; +def S8SUBL : OForm< 0x10, 0x1B, "s8subl $RA,$RB,$RC", + [(set GPRC:$RC, (intop (sub8 GPRC:$RA, GPRC:$RB)))]>; +def S8SUBLi : OFormL<0x10, 0x1B, "s8subl $RA,$L,$RC", + [(set GPRC:$RC, (intop (sub8 GPRC:$RA, immUExt8:$L)))]>; +def S8SUBQ : OForm< 0x10, 0x3B, "s8subq $RA,$RB,$RC", + [(set GPRC:$RC, (sub8 GPRC:$RA, GPRC:$RB))]>; +def S8SUBQi : OFormL<0x10, 0x3B, "s8subq $RA,$L,$RC", + [(set GPRC:$RC, (sub8 GPRC:$RA, immUExt8:$L))]>; +def SEXTB : OForm2<0x1C, 0x00, "sextb $RB,$RC", + [(set GPRC:$RC, (sext_inreg GPRC:$RB, i8))]>; +def SEXTW : OForm2<0x1C, 0x01, "sextw $RB,$RC", + [(set GPRC:$RC, (sext_inreg GPRC:$RB, i16))]>; +def SL : OForm< 0x12, 0x39, "sll $RA,$RB,$RC", + [(set GPRC:$RC, (shl GPRC:$RA, GPRC:$RB))]>; +def SLi : OFormL<0x12, 0x39, "sll $RA,$L,$RC", + [(set GPRC:$RC, (shl GPRC:$RA, immUExt8:$L))]>; +def SRA : OForm< 0x12, 0x3C, "sra $RA,$RB,$RC", + [(set GPRC:$RC, (sra GPRC:$RA, GPRC:$RB))]>; +def SRAi : OFormL<0x12, 0x3C, "sra $RA,$L,$RC", + [(set GPRC:$RC, (sra GPRC:$RA, immUExt8:$L))]>; +def SRL : OForm< 0x12, 0x34, "srl $RA,$RB,$RC", + [(set GPRC:$RC, (srl GPRC:$RA, GPRC:$RB))]>; +def SRLi : OFormL<0x12, 0x34, "srl $RA,$L,$RC", + [(set GPRC:$RC, (srl GPRC:$RA, immUExt8:$L))]>; +def SUBL : OForm< 0x10, 0x09, "subl $RA,$RB,$RC", + [(set GPRC:$RC, (intop (sub GPRC:$RA, GPRC:$RB)))]>; +def SUBLi : OFormL<0x10, 0x09, "subl $RA,$L,$RC", + [(set GPRC:$RC, (intop (sub GPRC:$RA, immUExt8:$L)))]>; +def SUBQ : OForm< 0x10, 0x29, "subq $RA,$RB,$RC", + [(set GPRC:$RC, (sub GPRC:$RA, GPRC:$RB))]>; +def SUBQi : OFormL<0x10, 0x29, "subq $RA,$L,$RC", + [(set GPRC:$RC, (sub GPRC:$RA, immUExt8:$L))]>; +def UMULH : OForm< 0x13, 0x30, "umulh $RA,$RB,$RC", + [(set GPRC:$RC, (mulhu GPRC:$RA, GPRC:$RB))]>; +def UMULHi : OFormL<0x13, 0x30, "umulh $RA,$L,$RC", + [(set GPRC:$RC, (mulhu GPRC:$RA, immUExt8:$L))]>; +def XOR : OForm< 0x11, 0x40, "xor $RA,$RB,$RC", + [(set GPRC:$RC, (xor GPRC:$RA, GPRC:$RB))]>; +def XORi : OFormL<0x11, 0x40, "xor $RA,$L,$RC", + [(set GPRC:$RC, (xor GPRC:$RA, immUExt8:$L))]>; +//FIXME: what to do about zap? the cases it catches are very complex +def ZAP : OForm< 0x12, 0x30, "zap $RA,$RB,$RC", []>; //Zero bytes +//ZAPi is useless give ZAPNOTi +def ZAPi : OFormL<0x12, 0x30, "zap $RA,$L,$RC", []>; //Zero bytes +//FIXME: what to do about zapnot? see ZAP :) +def ZAPNOT : OForm< 0x12, 0x31, "zapnot $RA,$RB,$RC", []>; //Zero bytes not +def ZAPNOTi : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC", + [(set GPRC:$RC, (and GPRC:$RA, immZAP:$L))]>; //Comparison, int -def CMPBGE : OForm< 0x10, 0x0F, "cmpbge $RA,$RB,$RC">; //Compare byte -def CMPBGEi : OFormL<0x10, 0x0F, "cmpbge $RA,$L,$RC">; //Compare byte -def CMPEQ : OForm< 0x10, 0x2D, "cmpeq $RA,$RB,$RC">; //Compare signed quadword equal -def CMPEQi : OFormL<0x10, 0x2D, "cmpeq $RA,$L,$RC">; //Compare signed quadword equal -def CMPLE : OForm< 0x10, 0x6D, "cmple $RA,$RB,$RC">; //Compare signed quadword less than or equal -def CMPLEi : OFormL<0x10, 0x6D, "cmple $RA,$L,$RC">; //Compare signed quadword less than or equal -def CMPLT : OForm< 0x10, 0x4D, "cmplt $RA,$RB,$RC">; //Compare signed quadword less than -def CMPLTi : OFormL<0x10, 0x4D, "cmplt $RA,$L,$RC">; //Compare signed quadword less than -def CMPULE : OForm< 0x10, 0x3D, "cmpule $RA,$RB,$RC">; //Compare unsigned quadword less than or equal -def CMPULEi : OFormL<0x10, 0x3D, "cmpule $RA,$L,$RC">; //Compare unsigned quadword less than or equal -def CMPULT : OForm< 0x10, 0x1D, "cmpult $RA,$RB,$RC">; //Compare unsigned quadword less than -def CMPULTi : OFormL<0x10, 0x1D, "cmpult $RA,$L,$RC">; //Compare unsigned quadword less than - -//Comparison, FP -def CMPTEQ : FPForm<0x16, 0x0A5, "cmpteq/su $RA,$RB,$RC">; //Compare T_floating equal -def CMPTLE : FPForm<0x16, 0x0A7, "cmptle/su $RA,$RB,$RC">; //Compare T_floating less than or equal -def CMPTLT : FPForm<0x16, 0x0A6, "cmptlt/su $RA,$RB,$RC">; //Compare T_floating less than -def CMPTUN : FPForm<0x16, 0x0A4, "cmptun/su $RA,$RB,$RC">; //Compare T_floating unordered +//So this is a waste of what this instruction can do, but it still saves something +def CMPBGE : OForm< 0x10, 0x0F, "cmpbge $RA,$RB,$RC", + [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), (and GPRC:$RB, 255)))]>; +def CMPBGEi : OFormL<0x10, 0x0F, "cmpbge $RA,$L,$RC", + [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), immUExt8:$L))]>; +def CMPEQ : OForm< 0x10, 0x2D, "cmpeq $RA,$RB,$RC", + [(set GPRC:$RC, (seteq GPRC:$RA, GPRC:$RB))]>; +def CMPEQi : OFormL<0x10, 0x2D, "cmpeq $RA,$L,$RC", + [(set GPRC:$RC, (seteq GPRC:$RA, immUExt8:$L))]>; +def CMPLE : OForm< 0x10, 0x6D, "cmple $RA,$RB,$RC", + [(set GPRC:$RC, (setle GPRC:$RA, GPRC:$RB))]>; +def CMPLEi : OFormL<0x10, 0x6D, "cmple $RA,$L,$RC", + [(set GPRC:$RC, (setle GPRC:$RA, immUExt8:$L))]>; +def CMPLT : OForm< 0x10, 0x4D, "cmplt $RA,$RB,$RC", + [(set GPRC:$RC, (setlt GPRC:$RA, GPRC:$RB))]>; +def CMPLTi : OFormL<0x10, 0x4D, "cmplt $RA,$L,$RC", + [(set GPRC:$RC, (setlt GPRC:$RA, immUExt8:$L))]>; +def CMPULE : OForm< 0x10, 0x3D, "cmpule $RA,$RB,$RC", + [(set GPRC:$RC, (setule GPRC:$RA, GPRC:$RB))]>; +def CMPULEi : OFormL<0x10, 0x3D, "cmpule $RA,$L,$RC", + [(set GPRC:$RC, (setule GPRC:$RA, immUExt8:$L))]>; +def CMPULT : OForm< 0x10, 0x1D, "cmpult $RA,$RB,$RC", + [(set GPRC:$RC, (setlt GPRC:$RA, GPRC:$RB))]>; +def CMPULTi : OFormL<0x10, 0x1D, "cmpult $RA,$L,$RC", + [(set GPRC:$RC, (setlt GPRC:$RA, immUExt8:$L))]>; + +//Patterns for unsupported int comparisons +def : Pat<(setueq GPRC:$X, GPRC:$Y), (CMPEQ GPRC:$X, GPRC:$Y)>; +def : Pat<(setueq GPRC:$X, immUExt8:$Y), (CMPEQi GPRC:$X, immUExt8:$Y)>; + +def : Pat<(setugt GPRC:$X, GPRC:$Y), (CMPULT GPRC:$Y, GPRC:$X)>; +def : Pat<(setugt immUExt8:$X, GPRC:$Y), (CMPULTi GPRC:$Y, immUExt8:$X)>; + +def : Pat<(setuge GPRC:$X, GPRC:$Y), (CMPULE GPRC:$Y, GPRC:$X)>; +def : Pat<(setuge immUExt8:$X, GPRC:$Y), (CMPULEi GPRC:$Y, immUExt8:$X)>; + +def : Pat<(setgt GPRC:$X, GPRC:$Y), (CMPLT GPRC:$Y, GPRC:$X)>; +def : Pat<(setgt immUExt8:$X, GPRC:$Y), (CMPLTi GPRC:$Y, immUExt8:$X)>; + +def : Pat<(setge GPRC:$X, GPRC:$Y), (CMPLE GPRC:$Y, GPRC:$X)>; +def : Pat<(setge immUExt8:$X, GPRC:$Y), (CMPLEi GPRC:$Y, immUExt8:$X)>; -//There are in the Multimedia extentions, so let's not use them yet -def MAXSB8 : OForm<0x1C, 0x3E, "MAXSB8 $RA,$RB,$RC">; //Vector signed byte maximum -def MAXSW4 : OForm< 0x1C, 0x3F, "MAXSW4 $RA,$RB,$RC">; //Vector signed word maximum -def MAXUB8 : OForm<0x1C, 0x3C, "MAXUB8 $RA,$RB,$RC">; //Vector unsigned byte maximum -def MAXUW4 : OForm< 0x1C, 0x3D, "MAXUW4 $RA,$RB,$RC">; //Vector unsigned word maximum -def MINSB8 : OForm< 0x1C, 0x38, "MINSB8 $RA,$RB,$RC">; //Vector signed byte minimum -def MINSW4 : OForm< 0x1C, 0x39, "MINSW4 $RA,$RB,$RC">; //Vector signed word minimum -def MINUB8 : OForm< 0x1C, 0x3A, "MINUB8 $RA,$RB,$RC">; //Vector unsigned byte minimum -def MINUW4 : OForm< 0x1C, 0x3B, "MINUW4 $RA,$RB,$RC">; //Vector unsigned word minimum -def PERR : OForm< 0x1C, 0x31, "PERR $RA,$RB,$RC">; //Pixel error -def PKLB : OForm< 0x1C, 0x37, "PKLB $RA,$RB,$RC">; //Pack longwords to bytes -def PKWB : OForm<0x1C, 0x36, "PKWB $RA,$RB,$RC">; //Pack words to bytes -def UNPKBL : OForm< 0x1C, 0x35, "UNPKBL $RA,$RB,$RC">; //Unpack bytes to longwords -def UNPKBW : OForm< 0x1C, 0x34, "UNPKBW $RA,$RB,$RC">; //Unpack bytes to words +def : Pat<(setne GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>; +def : Pat<(setne GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQi GPRC:$X, immUExt8:$Y), 0)>; -//End operate +def : Pat<(setune GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>; +def : Pat<(setune GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQ GPRC:$X, immUExt8:$Y), 0)>; -let isReturn = 1, isTerminator = 1 in + +let isReturn = 1, isTerminator = 1 in def RET : MbrForm< 0x1A, 0x02, (ops GPRC:$RD, GPRC:$RS, s64imm:$DISP), "ret $RD,($RS),$DISP">; //Return from subroutine +//DAG Version: +let isReturn = 1, isTerminator = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in + def RETDAG : MbrForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1">; //Return from subroutine def JMP : MbrForm< 0x1A, 0x00, (ops GPRC:$RD, GPRC:$RS, GPRC:$DISP), "jmp $RD,($RS),$DISP">; //Jump let isCall = 1, @@ -267,12 +373,22 @@ def JSR : MbrForm< 0x1A, 0x01, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr $RD,($RS),$DISP">; //Jump to subroutine def BSR : BForm<0x34, "bsr $RA,$DISP">; //Branch to subroutine } +let isCall = 1, + Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, + R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, + F0, F1, + F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, + F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R27, R29] in { + def JSRDAG : MbrForm< 0x1A, 0x01, (ops ), "jsr $$26,($$27),0">; //Jump to subroutine +} let isCall = 1, Defs = [R24, R25, R27, R28], Uses = [R24, R25] in def JSRs : MbrForm< 0x1A, 0x01, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr $RD,($RS),$DISP">; //Jump to div or rem def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP">; //Jump to subroutine return def BR : BForm<0x30, "br $RA,$DISP">; //Branch +def BR_DAG : BFormD<0x30, "br $$31,$DISP">; //Branch + //Stores, int def STB : MForm<0x0E, "stb $RA,$DISP($RB)">; // Store byte def STW : MForm<0x0D, "stw $RA,$DISP($RB)">; // Store word @@ -349,64 +465,130 @@ def FBLT : FBForm<0x32, "fblt $RA,$DISP">; //Floating branch if < zero def FBNE : FBForm<0x35, "fbne $RA,$DISP">; //Floating branch if != zero -//Funky Floating point ops -def CPYS : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC">; //Copy sign -def CPYSE : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC">; //Copy sign and exponent -def CPYSN : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC">; //Copy sign negate +def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA">; //Read process cycle counter //Basic Floating point ops -def ADDS : FPForm<0x16, 0x580, "adds/su $RA,$RB,$RC">; //Add S_floating -def ADDT : FPForm<0x16, 0x5A0, "addt/su $RA,$RB,$RC">; //Add T_floating -def SUBS : FPForm<0x16, 0x581, "subs/su $RA,$RB,$RC">; //Subtract S_floating -def SUBT : FPForm<0x16, 0x5A1, "subt/su $RA,$RB,$RC">; //Subtract T_floating -def DIVS : FPForm<0x16, 0x583, "divs/su $RA,$RB,$RC">; //Divide S_floating -def DIVT : FPForm<0x16, 0x5A3, "divt/su $RA,$RB,$RC">; //Divide T_floating -def MULS : FPForm<0x16, 0x582, "muls/su $RA,$RB,$RC">; //Multiply S_floating -def MULT : FPForm<0x16, 0x5A2, "mult/su $RA,$RB,$RC">; //Multiply T_floating -def SQRTS : FPForm<0x14, 0x58B, "sqrts/su $RA,$RB,$RC">; //Square root S_floating -def SQRTT : FPForm<0x14, 0x5AB, "sqrtt/su $RA,$RB,$RC">; //Square root T_floating - -//INT reg to FP reg and back again -//not supported on 21164 -def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC">; //Floating to integer move, S_floating -def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC">; //Floating to integer move, T_floating -def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC">; //Integer to floating move, S_floating -def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC">; //Integer to floating move, T_floating -//CVTLQ F-P 17.010 Convert longword to quadword -//CVTQL F-P 17.030 Convert quadword to longword -//These use SW completion, may not have function code for that set right (matters for JIT) -def CVTQS : FPForm<0x16, 0x0BC, "cvtqs $RB,$RC">; //Convert quadword to S_floating -def CVTQT : FPForm<0x16, 0x0BE, "cvtqt $RB,$RC">; //Convert quadword to T_floating -def CVTST : FPForm<0x16, 0x2AC, "cvtsts $RB,$RC">; //Convert S_floating to T_floating -def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC">; //Convert T_floating to quadword -def CVTTS : FPForm<0x16, 0x5AC, "cvtts/su $RB,$RC">; //Convert T_floating to S_floating +//Floats + +let OperandList = (ops F4RC:$RC, F4RC:$RB), Fa = 31 in +def SQRTS : FPForm<0x14, 0x58B, "sqrts/su $RB,$RC", + [(set F4RC:$RC, (fsqrt F4RC:$RB))]>; + +let OperandList = (ops F4RC:$RC, F4RC:$RA, F4RC:$RB) in { +def ADDS : FPForm<0x16, 0x580, "adds/su $RA,$RB,$RC", + [(set F4RC:$RC, (fadd F4RC:$RA, F4RC:$RB))]>; +def SUBS : FPForm<0x16, 0x581, "subs/su $RA,$RB,$RC", + [(set F4RC:$RC, (fsub F4RC:$RA, F4RC:$RB))]>; +def DIVS : FPForm<0x16, 0x583, "divs/su $RA,$RB,$RC", + [(set F4RC:$RC, (fdiv F4RC:$RA, F4RC:$RB))]>; +def MULS : FPForm<0x16, 0x582, "muls/su $RA,$RB,$RC", + [(set F4RC:$RC, (fmul F4RC:$RA, F4RC:$RB))]>; + +def CPYSS : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",[]>; //Copy sign +def CPYSES : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[]>; //Copy sign and exponent +def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",[]>; //Copy sign negate +} + +//Doubles + +let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in +def SQRTT : FPForm<0x14, 0x5AB, "sqrtt/su $RB,$RC", + [(set F8RC:$RC, (fsqrt F8RC:$RB))]>; + +let OperandList = (ops F8RC:$RC, F8RC:$RA, F8RC:$RB) in { +def ADDT : FPForm<0x16, 0x5A0, "addt/su $RA,$RB,$RC", + [(set F8RC:$RC, (fadd F8RC:$RA, F8RC:$RB))]>; +def SUBT : FPForm<0x16, 0x5A1, "subt/su $RA,$RB,$RC", + [(set F8RC:$RC, (fsub F8RC:$RA, F8RC:$RB))]>; +def DIVT : FPForm<0x16, 0x5A3, "divt/su $RA,$RB,$RC", + [(set F8RC:$RC, (fdiv F8RC:$RA, F8RC:$RB))]>; +def MULT : FPForm<0x16, 0x5A2, "mult/su $RA,$RB,$RC", + [(set F8RC:$RC, (fmul F8RC:$RA, F8RC:$RB))]>; + +def CPYST : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",[]>; //Copy sign +def CPYSET : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[]>; //Copy sign and exponent +def CPYSNT : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",[]>; //Copy sign negate + +def CMPTEQ : FPForm<0x16, 0x5A5, "cmpteq/su $RA,$RB,$RC", []>; +// [(set F8RC:$RC, (seteq F8RC:$RA, F8RC:$RB))]>; +def CMPTLE : FPForm<0x16, 0x5A7, "cmptle/su $RA,$RB,$RC", []>; +// [(set F8RC:$RC, (setle F8RC:$RA, F8RC:$RB))]>; +def CMPTLT : FPForm<0x16, 0x5A6, "cmptlt/su $RA,$RB,$RC", []>; +// [(set F8RC:$RC, (setlt F8RC:$RA, F8RC:$RB))]>; +def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", []>; +// [(set F8RC:$RC, (setuo F8RC:$RA, F8RC:$RB))]>; +} +//TODO: Add lots more FP patterns + + + +let OperandList = (ops GPRC:$RC, F4RC:$RA), Fb = 31 in +def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC",[]>; //Floating to integer move, S_floating +let OperandList = (ops GPRC:$RC, F8RC:$RA), Fb = 31 in +def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC",[]>; //Floating to integer move, T_floating +let OperandList = (ops F4RC:$RC, GPRC:$RA), Fb = 31 in +def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC",[]>; //Integer to floating move, S_floating +let OperandList = (ops F8RC:$RC, GPRC:$RA), Fb = 31 in +def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC",[]>; //Integer to floating move, T_floating + + +let OperandList = (ops F4RC:$RC, F8RC:$RB), Fa = 31 in +def CVTQS : FPForm<0x16, 0x7BC, "cvtqs/sui $RB,$RC",[]>; //Convert quadword to S_floating +let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in +def CVTQT : FPForm<0x16, 0x7BE, "cvtqt/sui $RB,$RC",[]>; //Convert quadword to T_floating +let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in +def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC",[]>; //Convert T_floating to quadword +let OperandList = (ops F8RC:$RC, F4RC:$RB), Fa = 31 in +def CVTST : FPForm<0x16, 0x6AC, "cvtst/s $RB,$RC", + [(set F8RC:$RC, (fextend F4RC:$RB))]>; +let OperandList = (ops F4RC:$RC, F8RC:$RB), Fa = 31 in +def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC", + [(set F4RC:$RC, (fround F8RC:$RB))]>; //S_floating : IEEE Single //T_floating : IEEE Double +//Unused instructions //Mnemonic Format Opcode Description - //CALL_PAL Pcd 00 Trap to PALcode //ECB Mfc 18.E800 Evict cache block //EXCB Mfc 18.0400 Exception barrier //FETCH Mfc 18.8000 Prefetch data //FETCH_M Mfc 18.A000 Prefetch data, modify intent - //LDL_L Mem 2A Load sign-extended longword locked //LDQ_L Mem 2B Load quadword locked //LDQ_U Mem 0B Load unaligned quadword //MB Mfc 18.4000 Memory barrier -//RPCC Mfc 18.C000 Read process cycle counter - //STL_C Mem 2E Store longword conditional //STQ_C Mem 2F Store quadword conditional //STQ_U Mem 0F Store unaligned quadword - //TRAPB Mfc 18.0000 Trap barrier //WH64 Mfc 18.F800 Write hint  64 bytes //WMB Mfc 18.4400 Write memory barrier - - //MF_FPCR F-P 17.025 Move from FPCR //MT_FPCR F-P 17.024 Move to FPCR +//There are in the Multimedia extentions, so let's not use them yet +//def MAXSB8 : OForm<0x1C, 0x3E, "MAXSB8 $RA,$RB,$RC">; //Vector signed byte maximum +//def MAXSW4 : OForm< 0x1C, 0x3F, "MAXSW4 $RA,$RB,$RC">; //Vector signed word maximum +//def MAXUB8 : OForm<0x1C, 0x3C, "MAXUB8 $RA,$RB,$RC">; //Vector unsigned byte maximum +//def MAXUW4 : OForm< 0x1C, 0x3D, "MAXUW4 $RA,$RB,$RC">; //Vector unsigned word maximum +//def MINSB8 : OForm< 0x1C, 0x38, "MINSB8 $RA,$RB,$RC">; //Vector signed byte minimum +//def MINSW4 : OForm< 0x1C, 0x39, "MINSW4 $RA,$RB,$RC">; //Vector signed word minimum +//def MINUB8 : OForm< 0x1C, 0x3A, "MINUB8 $RA,$RB,$RC">; //Vector unsigned byte minimum +//def MINUW4 : OForm< 0x1C, 0x3B, "MINUW4 $RA,$RB,$RC">; //Vector unsigned word minimum +//def PERR : OForm< 0x1C, 0x31, "PERR $RA,$RB,$RC">; //Pixel error +//def PKLB : OForm< 0x1C, 0x37, "PKLB $RA,$RB,$RC">; //Pack longwords to bytes +//def PKWB : OForm<0x1C, 0x36, "PKWB $RA,$RB,$RC">; //Pack words to bytes +//def UNPKBL : OForm< 0x1C, 0x35, "UNPKBL $RA,$RB,$RC">; //Unpack bytes to longwords +//def UNPKBW : OForm< 0x1C, 0x34, "UNPKBW $RA,$RB,$RC">; //Unpack bytes to words +//CVTLQ F-P 17.010 Convert longword to quadword +//CVTQL F-P 17.030 Convert quadword to longword +//def AMASK : OForm< 0x11, 0x61, "AMASK $RA,$RB,$RC", []>; //Architecture mask +//def AMASKi : OFormL<0x11, 0x61, "AMASK $RA,$L,$RC", []>; //Architecture mask + + + + +def : Pat<(i64 immSExt16:$imm), + (LDA immSExt16:$imm, R31)>; Index: llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp diff -u llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.28 llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.28.2.1 --- llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.28 Sun Oct 9 15:11:35 2005 +++ llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp Wed Nov 16 12:32:33 2005 @@ -65,13 +65,6 @@ { } -static const TargetRegisterClass *getClass(unsigned SrcReg) { - if (Alpha::FPRCRegisterClass->contains(SrcReg)) - return Alpha::FPRCRegisterClass; - assert(Alpha::GPRCRegisterClass->contains(SrcReg) && "Reg not FPR or GPR"); - return Alpha::GPRCRegisterClass; -} - void AlphaRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, @@ -82,9 +75,11 @@ if (EnableAlphaLSMark) BuildMI(MBB, MI, Alpha::MEMLABEL, 4).addImm(4).addImm(0).addImm(1) .addImm(getUID()); - if (getClass(SrcReg) == Alpha::FPRCRegisterClass) + if (RC == Alpha::F4RCRegisterClass) + BuildMI(MBB, MI, Alpha::STS, 3).addReg(SrcReg).addFrameIndex(FrameIdx).addReg(Alpha::F31); + else if (RC == Alpha::F8RCRegisterClass) BuildMI(MBB, MI, Alpha::STT, 3).addReg(SrcReg).addFrameIndex(FrameIdx).addReg(Alpha::F31); - else if (getClass(SrcReg) == Alpha::GPRCRegisterClass) + else if (RC == Alpha::GPRCRegisterClass) BuildMI(MBB, MI, Alpha::STQ, 3).addReg(SrcReg).addFrameIndex(FrameIdx).addReg(Alpha::F31); else abort(); @@ -99,9 +94,11 @@ if (EnableAlphaLSMark) BuildMI(MBB, MI, Alpha::MEMLABEL, 4).addImm(4).addImm(0).addImm(2) .addImm(getUID()); - if (getClass(DestReg) == Alpha::FPRCRegisterClass) + if (RC == Alpha::F4RCRegisterClass) + BuildMI(MBB, MI, Alpha::LDS, 2, DestReg).addFrameIndex(FrameIdx).addReg(Alpha::F31); + else if (RC == Alpha::F8RCRegisterClass) BuildMI(MBB, MI, Alpha::LDT, 2, DestReg).addFrameIndex(FrameIdx).addReg(Alpha::F31); - else if (getClass(DestReg) == Alpha::GPRCRegisterClass) + else if (RC == Alpha::GPRCRegisterClass) BuildMI(MBB, MI, Alpha::LDQ, 2, DestReg).addFrameIndex(FrameIdx).addReg(Alpha::F31); else abort(); @@ -126,6 +123,50 @@ return 0; } +MachineInstr *AlphaRegisterInfo::foldMemoryOperand(MachineInstr *MI, + unsigned OpNum, + int FrameIndex) const { + // Make sure this is a reg-reg copy. + unsigned Opc = MI->getOpcode(); + + if ((Opc == Alpha::BIS && + MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) { + if (OpNum == 0) { // move -> store + unsigned InReg = MI->getOperand(1).getReg(); + return BuildMI(Alpha::STQ, 3).addReg(InReg).addFrameIndex(FrameIndex) + .addReg(Alpha::F31); + } else { // load -> move + unsigned OutReg = MI->getOperand(0).getReg(); + return BuildMI(Alpha::LDQ, 2, OutReg).addFrameIndex(FrameIndex) + .addReg(Alpha::F31); + } + } else if ((Opc == Alpha::CPYSS && + MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) { + if (OpNum == 0) { // move -> store + unsigned InReg = MI->getOperand(1).getReg(); + return BuildMI(Alpha::STS, 3).addReg(InReg).addFrameIndex(FrameIndex) + .addReg(Alpha::F31); + } else { // load -> move + unsigned OutReg = MI->getOperand(0).getReg(); + return BuildMI(Alpha::LDS, 2, OutReg).addFrameIndex(FrameIndex) + .addReg(Alpha::F31); + } + } else if ((Opc == Alpha::CPYST && + MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) { + if (OpNum == 0) { // move -> store + unsigned InReg = MI->getOperand(1).getReg(); + return BuildMI(Alpha::STT, 3).addReg(InReg).addFrameIndex(FrameIndex) + .addReg(Alpha::F31); + } else { // load -> move + unsigned OutReg = MI->getOperand(0).getReg(); + return BuildMI(Alpha::LDT, 2, OutReg).addFrameIndex(FrameIndex) + .addReg(Alpha::F31); + } + } + return 0; +} + + void AlphaRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SrcReg, @@ -133,8 +174,10 @@ // std::cerr << "copyRegToReg " << DestReg << " <- " << SrcReg << "\n"; if (RC == Alpha::GPRCRegisterClass) { BuildMI(MBB, MI, Alpha::BIS, 2, DestReg).addReg(SrcReg).addReg(SrcReg); - } else if (RC == Alpha::FPRCRegisterClass) { - BuildMI(MBB, MI, Alpha::CPYS, 2, DestReg).addReg(SrcReg).addReg(SrcReg); + } else if (RC == Alpha::F4RCRegisterClass) { + BuildMI(MBB, MI, Alpha::CPYSS, 2, DestReg).addReg(SrcReg).addReg(SrcReg); + } else if (RC == Alpha::F8RCRegisterClass) { + BuildMI(MBB, MI, Alpha::CPYST, 2, DestReg).addReg(SrcReg).addReg(SrcReg); } else { std::cerr << "Attempt to copy register that is not GPR or FPR"; abort(); @@ -314,7 +357,7 @@ MachineBasicBlock &MBB) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); MachineBasicBlock::iterator MBBI = prior(MBB.end()); - assert((MBBI->getOpcode() == Alpha::RET) + assert(((MBBI->getOpcode() == Alpha::RET) || (MBBI->getOpcode() == Alpha::RETDAG)) && "Can only insert epilog into returning blocks"); bool FP = hasFP(MF); Index: llvm/lib/Target/Alpha/AlphaRegisterInfo.h diff -u llvm/lib/Target/Alpha/AlphaRegisterInfo.h:1.7 llvm/lib/Target/Alpha/AlphaRegisterInfo.h:1.7.2.1 --- llvm/lib/Target/Alpha/AlphaRegisterInfo.h:1.7 Sun Oct 9 15:11:35 2005 +++ llvm/lib/Target/Alpha/AlphaRegisterInfo.h Wed Nov 16 12:32:33 2005 @@ -37,6 +37,9 @@ virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; + MachineInstr* foldMemoryOperand(MachineInstr *MI, unsigned OpNum, + int FrameIndex) const; + void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const; Index: llvm/lib/Target/Alpha/AlphaRegisterInfo.td diff -u llvm/lib/Target/Alpha/AlphaRegisterInfo.td:1.12 llvm/lib/Target/Alpha/AlphaRegisterInfo.td:1.12.2.1 --- llvm/lib/Target/Alpha/AlphaRegisterInfo.td:1.12 Fri Aug 19 13:50:46 2005 +++ llvm/lib/Target/Alpha/AlphaRegisterInfo.td Wed Nov 16 12:32:33 2005 @@ -82,20 +82,59 @@ def GPRC : RegisterClass<"Alpha", i64, 64, // Volatile [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22, - R23, R24, R25, + R23, R24, R25, R28, //Special meaning, but volatile R27, //procedure address R26, //return address R29, //global offset table address // Non-volatile - R9, R10, R11, R12, R13, R14 ]>; - // Note: R28 is reserved for the assembler + R9, R10, R11, R12, R13, R14, + R31 ]> //zero +{ + let MethodProtos = [{ + iterator allocation_order_end(MachineFunction &MF) const; + }]; + let MethodBodies = [{ + GPRCClass::iterator + GPRCClass::allocation_order_end(MachineFunction &MF) const { + return end()-1; + } + }]; +} -// Don't allocate 15, 29, 30, 31 -// Allocation volatiles only for now -def FPRC : RegisterClass<"Alpha", f64, 64, [F0, F1, +def F4RC : RegisterClass<"Alpha", f32, 64, [F0, F1, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, // Saved: - F2, F3, F4, F5, F6, F7, F8, F9 - ]>; + F2, F3, F4, F5, F6, F7, F8, F9, + F31 ]> //zero +{ + let MethodProtos = [{ + iterator allocation_order_end(MachineFunction &MF) const; + }]; + let MethodBodies = [{ + F4RCClass::iterator + F4RCClass::allocation_order_end(MachineFunction &MF) const { + return end()-1; + } + }]; +} + +def F8RC : RegisterClass<"Alpha", f64, 64, [F0, F1, + F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, + F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, + // Saved: + F2, F3, F4, F5, F6, F7, F8, F9, + F31 ]> //zero +{ + let MethodProtos = [{ + iterator allocation_order_end(MachineFunction &MF) const; + }]; + let MethodBodies = [{ + F8RCClass::iterator + F8RCClass::allocation_order_end(MachineFunction &MF) const { + return end()-1; + } + }]; +} + Index: llvm/lib/Target/Alpha/AlphaSubtarget.cpp diff -u llvm/lib/Target/Alpha/AlphaSubtarget.cpp:1.3 llvm/lib/Target/Alpha/AlphaSubtarget.cpp:1.3.2.1 --- llvm/lib/Target/Alpha/AlphaSubtarget.cpp:1.3 Sun Oct 2 02:13:52 2005 +++ llvm/lib/Target/Alpha/AlphaSubtarget.cpp Wed Nov 16 12:32:33 2005 @@ -13,49 +13,13 @@ #include "AlphaSubtarget.h" #include "Alpha.h" -#include "llvm/Module.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Target/SubtargetFeature.h" -#include "llvm/Support/Debug.h" - +#include "AlphaGenSubtarget.inc" using namespace llvm; -enum AlphaFeature { - AlphaFeatureCIX = 1 << 0, - AlphaFeatureFIX = 1 << 1, -}; - -/// Sorted (by key) array of values for CPU subtype. -static const SubtargetFeatureKV AlphaSubTypeKV[] = { - { "ev56" , "Select the Alpha EV56 processor", 0 }, - { "ev6" , "Select the Alpha EV6 processor", AlphaFeatureFIX }, - { "ev67" , "Select the Alpha EV67 processor", AlphaFeatureFIX | AlphaFeatureCIX }, - { "generic", "Select instructions for a generic Alpha processor (EV56)", 0 }, - { "pca56" , "Select the Alpha PCA56 processor", 0 }, -}; - -/// Length of AlphaSubTypeKV. -static const unsigned AlphaSubTypeKVSize = sizeof(AlphaSubTypeKV) - / sizeof(SubtargetFeatureKV); - -/// Sorted (by key) array of values for CPU features. -static SubtargetFeatureKV AlphaFeatureKV[] = { - { "CIX", "Should CIX extentions be used" , AlphaFeatureCIX }, - { "FIX" , "Should FIX extentions be used" , AlphaFeatureFIX }, - }; -/// Length of AlphaFeatureKV. -static const unsigned AlphaFeatureKVSize = sizeof(AlphaFeatureKV) - / sizeof(SubtargetFeatureKV); - AlphaSubtarget::AlphaSubtarget(const Module &M, const std::string &FS) - :HasF2I(false), HasCT(false) -{ + : HasF2I(false), HasCT(false) { std::string CPU = "generic"; - uint32_t Bits = - SubtargetFeatures::Parse(FS, CPU, - AlphaSubTypeKV, AlphaSubTypeKVSize, - AlphaFeatureKV, AlphaFeatureKVSize); - HasF2I = (Bits & AlphaFeatureFIX) != 0; - HasCT = (Bits & AlphaFeatureCIX) != 0; + // Parse features string. + ParseSubtargetFeatures(FS, CPU); } Index: llvm/lib/Target/Alpha/AlphaSubtarget.h diff -u llvm/lib/Target/Alpha/AlphaSubtarget.h:1.1 llvm/lib/Target/Alpha/AlphaSubtarget.h:1.1.2.1 --- llvm/lib/Target/Alpha/AlphaSubtarget.h:1.1 Thu Sep 29 17:54:56 2005 +++ llvm/lib/Target/Alpha/AlphaSubtarget.h Wed Nov 16 12:32:33 2005 @@ -33,6 +33,10 @@ /// of the specified module. /// AlphaSubtarget(const Module &M, const std::string &FS); + + /// ParseSubtargetFeatures - Parses features string setting specified + /// subtarget options. Definition of function is auto generated by tblgen. + void ParseSubtargetFeatures(const std::string &FS, const std::string &CPU); bool hasF2I() const { return HasF2I; } bool hasCT() const { return HasCT; } Index: llvm/lib/Target/Alpha/AlphaTargetMachine.cpp diff -u llvm/lib/Target/Alpha/AlphaTargetMachine.cpp:1.13 llvm/lib/Target/Alpha/AlphaTargetMachine.cpp:1.13.2.1 --- llvm/lib/Target/Alpha/AlphaTargetMachine.cpp:1.13 Thu Sep 29 17:54:56 2005 +++ llvm/lib/Target/Alpha/AlphaTargetMachine.cpp Wed Nov 16 12:32:33 2005 @@ -29,8 +29,8 @@ } namespace llvm { - cl::opt EnableAlphaLSR("enable-lsr-for-alpha", - cl::desc("Enable LSR for Alpha (beta option!)"), + cl::opt EnableAlphaDAG("enable-dag-isel-for-alpha", + cl::desc("Enable DAG ISEL for Alpha (beta option!)"), cl::Hidden); } @@ -48,7 +48,7 @@ M.getPointerSize() != Module::AnyPointerSize) return 0; // Match for some other target - return 0; + return getJITMatchQuality()/2; } unsigned AlphaTargetMachine::getJITMatchQuality() { @@ -74,13 +74,11 @@ /// bool AlphaTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType) { + CodeGenFileType FileType, + bool Fast) { if (FileType != TargetMachine::AssemblyFile) return true; - if (EnableAlphaLSR) { - PM.add(createLoopStrengthReducePass()); - PM.add(createCFGSimplificationPass()); - } + PM.add(createLoopStrengthReducePass()); // FIXME: Implement efficient support for garbage collection intrinsics. PM.add(createLowerGCPass()); @@ -94,7 +92,12 @@ // Make sure that no unreachable blocks are instruction selected. PM.add(createUnreachableBlockEliminationPass()); - PM.add(createAlphaPatternInstructionSelector(*this)); + PM.add(createCFGSimplificationPass()); + + if (EnableAlphaDAG) + PM.add(createAlphaISelDag(*this)); + else + PM.add(createAlphaPatternInstructionSelector(*this)); if (PrintMachineCode) PM.add(createMachineFunctionPrinterPass(&std::cerr)); @@ -117,10 +120,8 @@ void AlphaJITInfo::addPassesToJITCompile(FunctionPassManager &PM) { - if (EnableAlphaLSR) { - PM.add(createLoopStrengthReducePass()); - PM.add(createCFGSimplificationPass()); - } + PM.add(createLoopStrengthReducePass()); + PM.add(createCFGSimplificationPass()); // FIXME: Implement efficient support for garbage collection intrinsics. PM.add(createLowerGCPass()); Index: llvm/lib/Target/Alpha/AlphaTargetMachine.h diff -u llvm/lib/Target/Alpha/AlphaTargetMachine.h:1.10 llvm/lib/Target/Alpha/AlphaTargetMachine.h:1.10.2.1 --- llvm/lib/Target/Alpha/AlphaTargetMachine.h:1.10 Thu Sep 29 17:54:56 2005 +++ llvm/lib/Target/Alpha/AlphaTargetMachine.h Wed Nov 16 12:32:33 2005 @@ -48,17 +48,11 @@ static unsigned getJITMatchQuality(); - /// addPassesToEmitMachineCode - Add passes to the specified pass manager to - /// get machine code emitted. This uses a MachineCodeEmitter object to handle - /// actually outputting the machine code and resolving things like the address - /// of functions. This method should returns true if machine code emission is - /// not supported. - /// virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM, MachineCodeEmitter &MCE); virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType); + CodeGenFileType FileType, bool Fast); static unsigned getModuleMatchQuality(const Module &M); }; Index: llvm/lib/Target/Alpha/Makefile diff -u llvm/lib/Target/Alpha/Makefile:1.2 llvm/lib/Target/Alpha/Makefile:1.2.4.1 --- llvm/lib/Target/Alpha/Makefile:1.2 Mon Feb 21 22:58:26 2005 +++ llvm/lib/Target/Alpha/Makefile Wed Nov 16 12:32:33 2005 @@ -14,6 +14,7 @@ BUILT_SOURCES = AlphaGenRegisterInfo.h.inc AlphaGenRegisterNames.inc \ AlphaGenRegisterInfo.inc AlphaGenInstrNames.inc \ AlphaGenInstrInfo.inc AlphaGenCodeEmitter.inc \ - AlphaGenAsmWriter.inc + AlphaGenAsmWriter.inc AlphaGenDAGISel.inc \ + AlphaGenSubtarget.inc include $(LEVEL)/Makefile.common From bocchino at cs.uiuc.edu Wed Nov 16 12:32:20 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:20 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/AsmParser/Lexer.cpp Lexer.l llvmAsmParser.cpp llvmAsmParser.h llvmAsmParser.y Message-ID: <200511161832.MAA20824@zion.cs.uiuc.edu> Changes in directory llvm/lib/AsmParser: Lexer.cpp updated: 1.10.2.1 -> 1.10.2.2 Lexer.l updated: 1.64.2.1 -> 1.64.2.2 llvmAsmParser.cpp updated: 1.17.2.1 -> 1.17.2.2 llvmAsmParser.h updated: 1.9.2.1 -> 1.9.2.2 llvmAsmParser.y updated: 1.231.2.1 -> 1.231.2.2 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+3846 -2869) Lexer.cpp | 1160 ++++++------ Lexer.l | 2 llvmAsmParser.cpp | 5041 +++++++++++++++++++++++++++++++----------------------- llvmAsmParser.h | 379 ++-- llvmAsmParser.y | 111 - 5 files changed, 3846 insertions(+), 2847 deletions(-) Index: llvm/lib/AsmParser/Lexer.cpp diff -u llvm/lib/AsmParser/Lexer.cpp:1.10.2.1 llvm/lib/AsmParser/Lexer.cpp:1.10.2.2 --- llvm/lib/AsmParser/Lexer.cpp:1.10.2.1 Tue Oct 18 14:21:56 2005 +++ llvm/lib/AsmParser/Lexer.cpp Wed Nov 16 12:32:08 2005 @@ -20,7 +20,7 @@ /* A lexical scanner generated by flex */ /* Scanner skeleton version: - * $Header: /home/vadve/shared/PublicCVS/llvm/lib/AsmParser/Lexer.cpp,v 1.10.2.1 2005/10/18 19:21:56 bocchino Exp $ + * $Header: /home/vadve/shared/PublicCVS/llvm/lib/AsmParser/Lexer.cpp,v 1.10.2.2 2005/11/16 18:32:08 bocchino Exp $ */ #define FLEX_SCANNER @@ -28,6 +28,7 @@ #define YY_FLEX_MINOR_VERSION 5 #include +#include /* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ @@ -41,7 +42,6 @@ #ifdef __cplusplus #include -#include /* Use prototypes in function declarations. */ #define YY_USE_PROTOS @@ -308,35 +308,35 @@ *yy_cp = '\0'; \ yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 116 -#define YY_END_OF_BUFFER 117 -static yyconst short int yy_acclist[194] = +#define YY_NUM_RULES 118 +#define YY_END_OF_BUFFER 119 +static yyconst short int yy_acclist[196] = { 0, - 117, 115, 116, 114, 115, 116, 114, 116, 115, 116, - 115, 116, 115, 116, 115, 116, 115, 116, 115, 116, - 107, 115, 116, 107, 115, 116, 1, 115, 116, 115, - 116, 115, 116, 115, 116, 115, 116, 115, 116, 115, - 116, 115, 116, 115, 116, 115, 116, 115, 116, 115, - 116, 115, 116, 115, 116, 115, 116, 115, 116, 115, - 116, 115, 116, 115, 116, 115, 116, 115, 116, 115, - 116, 106, 104, 103, 103, 110, 108, 112, 107, 1, - 83, 33, 102, 58, 20, 106, 103, 103, 111, 112, - 17, 112, 113, 52, 57, 30, 34, 55, 3, 43, - - 54, 22, 72, 56, 82, 77, 78, 53, 59, 105, - 112, 112, 38, 73, 74, 90, 91, 45, 19, 109, - 23, 4, 50, 44, 95, 37, 11, 112, 2, 5, - 32, 47, 49, 39, 61, 65, 63, 64, 62, 60, - 41, 92, 40, 46, 18, 80, 89, 36, 48, 27, - 21, 35, 7, 85, 29, 88, 51, 75, 84, 24, - 25, 86, 42, 81, 79, 101, 67, 71, 69, 70, - 68, 66, 99, 6, 26, 97, 94, 76, 8, 14, - 9, 10, 31, 96, 12, 28, 87, 93, 13, 100, - 98, 15, 16 + 119, 117, 118, 116, 117, 118, 116, 118, 117, 118, + 117, 118, 117, 118, 117, 118, 117, 118, 117, 118, + 109, 117, 118, 109, 117, 118, 1, 117, 118, 117, + 118, 117, 118, 117, 118, 117, 118, 117, 118, 117, + 118, 117, 118, 117, 118, 117, 118, 117, 118, 117, + 118, 117, 118, 117, 118, 117, 118, 117, 118, 117, + 118, 117, 118, 117, 118, 117, 118, 117, 118, 117, + 118, 108, 106, 105, 105, 112, 110, 114, 109, 1, + 85, 35, 104, 60, 20, 108, 105, 105, 113, 114, + 17, 114, 115, 54, 59, 30, 36, 57, 3, 45, + + 56, 22, 74, 58, 84, 79, 80, 55, 61, 107, + 114, 114, 40, 75, 76, 92, 93, 47, 19, 111, + 23, 4, 52, 46, 97, 39, 11, 114, 33, 2, + 5, 32, 49, 51, 41, 63, 67, 65, 66, 64, + 62, 43, 94, 42, 48, 18, 82, 91, 38, 50, + 27, 21, 37, 7, 87, 29, 90, 53, 77, 86, + 24, 25, 88, 44, 83, 81, 103, 69, 73, 71, + 72, 70, 68, 101, 6, 26, 99, 34, 96, 78, + 8, 14, 9, 10, 31, 98, 12, 28, 89, 95, + 13, 102, 100, 15, 16 } ; -static yyconst short int yy_accept[463] = +static yyconst short int yy_accept[471] = { 0, 1, 1, 1, 2, 4, 7, 9, 11, 13, 15, 17, 19, 21, 24, 27, 30, 32, 34, 36, 38, @@ -351,44 +351,44 @@ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 87, 88, 90, 91, 92, 93, 93, - 94, 95, 95, 96, 96, 96, 97, 97, 97, 97, - 98, 98, 98, 98, 98, 98, 99, 99, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 101, - 101, 101, 101, 101, 101, 101, 101, 102, 103, 103, - 103, 104, 104, 105, 106, 106, 106, 106, 106, 107, - 107, 108, 108, 109, 109, 109, 109, 109, 109, 109, + 94, 95, 95, 95, 96, 96, 96, 97, 97, 97, + 97, 98, 98, 98, 98, 98, 98, 99, 99, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 101, 101, 101, 101, 101, 101, 101, 101, 102, 103, + 103, 103, 104, 104, 105, 106, 106, 106, 106, 106, + 106, 107, 107, 108, 108, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 110, - 110, 111, 112, 112, 112, 112, 113, 113, 113, 113, - 114, 115, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 118, 119, 119, 120, - 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 122, 122, 122, 123, 124, 124, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 126, 127, 127, 127, 127, 127, 128, 128, 129, 129, - 129, 130, 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 131, 131, 132, 133, 133, 133, 133, 133, - - 133, 134, 134, 134, 134, 134, 134, 135, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 143, 143, 143, - 144, 145, 146, 146, 146, 146, 146, 146, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 148, 148, 149, 149, 149, 149, 149, 150, 151, 152, - 152, 152, 153, 153, 154, 154, 154, 155, 155, 156, - 157, 158, 158, 159, 160, 161, 162, 162, 162, 163, - 164, 165, 166, 167, 167, 167, 167, 167, 168, 169, - 170, 171, 172, 173, 173, 173, 174, 174, 175, 176, - 176, 177, 177, 177, 177, 177, 177, 177, 177, 178, - - 178, 178, 179, 179, 179, 179, 180, 181, 181, 181, - 181, 182, 183, 183, 183, 183, 184, 185, 185, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 187, 187, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 189, 189, 190, 190, 191, 192, 193, 193, - 194, 194 + 109, 110, 110, 111, 112, 112, 112, 112, 113, 113, + 113, 113, 113, 114, 115, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 118, + 119, 119, 120, 120, 120, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 122, 122, 122, 123, + 124, 124, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 126, 127, 127, 127, 127, 127, + 128, 128, 129, 130, 130, 130, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 132, 132, 133, + + 134, 134, 134, 134, 134, 134, 135, 135, 135, 135, + 135, 135, 136, 136, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 144, 144, 144, 145, 146, 147, 147, + 147, 147, 147, 147, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 149, 149, 150, 150, + 150, 150, 150, 151, 152, 153, 153, 153, 154, 154, + 155, 155, 155, 156, 156, 157, 158, 159, 159, 159, + 160, 161, 162, 163, 163, 163, 164, 165, 166, 167, + 168, 168, 168, 168, 168, 169, 170, 171, 172, 173, + 174, 174, 174, 175, 175, 176, 177, 177, 178, 178, + + 178, 178, 178, 178, 179, 179, 179, 180, 180, 180, + 181, 181, 181, 181, 182, 183, 183, 183, 183, 184, + 185, 185, 185, 185, 186, 187, 187, 188, 188, 188, + 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, + 188, 188, 188, 188, 188, 188, 188, 188, 189, 189, + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 191, 191, 192, 192, 193, 194, 195, 195, 196, 196 } ; static yyconst int yy_ec[256] = @@ -432,117 +432,119 @@ 3 } ; -static yyconst short int yy_base[467] = +static yyconst short int yy_base[475] = { 0, - 0, 0, 964, 965, 965, 965, 959, 950, 34, 36, + 0, 0, 980, 981, 981, 981, 975, 966, 34, 36, 38, 42, 46, 50, 0, 51, 54, 53, 56, 61, 76, 77, 79, 80, 82, 83, 84, 90, 31, 111, - 110, 141, 164, 55, 100, 104, 957, 965, 948, 965, + 110, 141, 164, 55, 100, 104, 973, 981, 964, 981, 0, 123, 126, 145, 151, 119, 162, 181, 189, 0, - 132, 99, 145, 127, 41, 155, 112, 947, 152, 126, - 168, 193, 176, 190, 202, 204, 203, 205, 206, 207, - 136, 208, 209, 213, 215, 217, 230, 157, 222, 219, - 229, 946, 57, 945, 220, 239, 241, 223, 231, 243, - 253, 245, 248, 249, 256, 944, 260, 246, 251, 255, - - 267, 270, 275, 276, 282, 290, 286, 288, 297, 294, - 292, 298, 943, 0, 309, 311, 942, 318, 330, 0, - 941, 305, 940, 315, 322, 939, 331, 332, 311, 938, - 333, 336, 337, 338, 339, 937, 343, 344, 351, 352, - 340, 345, 355, 358, 356, 366, 370, 367, 369, 371, - 372, 374, 377, 379, 380, 383, 936, 935, 384, 385, - 934, 386, 933, 932, 408, 396, 392, 412, 931, 404, - 930, 409, 929, 397, 393, 422, 424, 426, 428, 431, - 432, 434, 436, 439, 438, 440, 441, 390, 442, 448, - 444, 446, 449, 394, 461, 468, 460, 450, 928, 452, - - 965, 473, 482, 486, 488, 491, 492, 462, 493, 927, - 926, 925, 494, 495, 474, 498, 496, 500, 502, 504, - 505, 506, 512, 513, 514, 516, 924, 517, 519, 518, - 525, 528, 529, 530, 534, 923, 922, 533, 921, 531, - 535, 0, 536, 540, 537, 541, 543, 553, 538, 554, - 560, 920, 556, 559, 919, 918, 568, 917, 569, 571, - 570, 573, 572, 575, 576, 579, 582, 584, 300, 916, - 915, 585, 587, 586, 603, 914, 588, 593, 593, 599, - 913, 604, 600, 616, 594, 613, 622, 606, 605, 624, - 625, 912, 626, 911, 910, 627, 629, 630, 634, 638, - - 909, 635, 639, 642, 645, 650, 908, 637, 907, 906, - 905, 904, 903, 902, 901, 900, 643, 640, 653, 899, - 898, 897, 656, 657, 658, 661, 665, 896, 667, 668, - 669, 670, 671, 673, 672, 677, 682, 687, 681, 895, - 675, 894, 693, 695, 697, 685, 893, 892, 891, 699, - 701, 890, 703, 889, 708, 709, 888, 711, 887, 886, - 885, 710, 884, 883, 882, 881, 713, 715, 880, 879, - 878, 877, 876, 716, 720, 721, 722, 875, 874, 873, - 872, 871, 870, 723, 725, 729, 728, 867, 858, 732, - 734, 739, 733, 740, 744, 741, 749, 752, 857, 756, - - 746, 853, 758, 759, 760, 852, 851, 761, 762, 764, - 849, 848, 769, 768, 766, 845, 843, 771, 842, 777, - 780, 773, 785, 774, 778, 792, 788, 794, 795, 797, - 798, 799, 800, 804, 802, 805, 806, 801, 809, 841, - 818, 840, 812, 819, 820, 823, 828, 826, 830, 831, - 832, 839, 833, 674, 838, 458, 350, 348, 835, 261, - 965, 871, 873, 179, 877, 138 + 132, 99, 145, 127, 41, 155, 152, 963, 168, 126, + 185, 203, 159, 193, 204, 206, 205, 130, 207, 167, + 208, 214, 209, 211, 215, 216, 218, 226, 230, 219, + 237, 962, 57, 961, 238, 240, 243, 244, 246, 247, + 257, 249, 250, 248, 255, 960, 260, 258, 263, 264, + + 265, 279, 282, 285, 129, 288, 280, 286, 297, 298, + 295, 307, 959, 0, 310, 312, 958, 314, 331, 0, + 957, 322, 318, 956, 325, 319, 955, 320, 324, 337, + 954, 338, 341, 340, 342, 343, 953, 344, 348, 345, + 355, 349, 351, 356, 363, 366, 369, 353, 352, 370, + 372, 373, 377, 380, 381, 383, 384, 952, 951, 385, + 386, 950, 387, 949, 948, 409, 397, 398, 392, 413, + 947, 388, 946, 402, 945, 410, 425, 426, 427, 396, + 429, 431, 432, 434, 435, 436, 439, 443, 441, 442, + 445, 449, 450, 452, 460, 457, 462, 463, 464, 469, + + 944, 470, 981, 482, 494, 473, 496, 499, 461, 477, + 486, 500, 943, 942, 941, 501, 502, 482, 504, 506, + 507, 511, 510, 512, 513, 514, 520, 524, 521, 940, + 525, 526, 528, 530, 534, 535, 536, 538, 939, 938, + 539, 937, 541, 543, 0, 546, 545, 542, 547, 552, + 559, 560, 556, 562, 563, 936, 564, 572, 935, 934, + 574, 933, 577, 576, 578, 580, 581, 584, 589, 590, + 592, 593, 594, 932, 931, 595, 597, 599, 612, 930, + 596, 604, 929, 617, 607, 928, 624, 613, 628, 604, + 626, 634, 635, 614, 636, 638, 927, 639, 926, 925, + + 640, 641, 600, 642, 648, 924, 644, 651, 647, 655, + 658, 923, 650, 662, 922, 921, 920, 919, 918, 917, + 916, 915, 663, 665, 669, 914, 913, 912, 666, 670, + 671, 672, 673, 911, 674, 680, 681, 683, 676, 686, + 682, 691, 694, 698, 687, 910, 692, 909, 706, 708, + 709, 710, 908, 907, 906, 711, 712, 905, 713, 904, + 719, 721, 903, 720, 902, 901, 900, 722, 723, 899, + 898, 897, 896, 724, 730, 895, 894, 893, 892, 891, + 731, 733, 736, 734, 890, 889, 888, 887, 886, 885, + 738, 739, 741, 744, 884, 883, 746, 749, 753, 747, + + 754, 759, 755, 880, 760, 766, 871, 763, 770, 869, + 773, 774, 775, 868, 865, 778, 780, 776, 864, 862, + 779, 783, 781, 861, 860, 782, 856, 794, 800, 784, + 801, 786, 789, 804, 805, 808, 811, 812, 813, 814, + 788, 816, 818, 820, 821, 822, 826, 855, 828, 854, + 834, 832, 835, 838, 840, 842, 841, 843, 844, 853, + 846, 474, 848, 395, 393, 269, 851, 224, 981, 884, + 886, 183, 890, 181 } ; -static yyconst short int yy_def[467] = +static yyconst short int yy_def[475] = { 0, - 461, 1, 461, 461, 461, 461, 462, 463, 464, 461, - 463, 463, 463, 463, 465, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 462, 461, 463, 461, - 466, 466, 461, 461, 463, 463, 463, 463, 463, 465, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 461, 466, 466, 461, 463, 463, 463, 49, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 49, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - - 461, 461, 461, 461, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 165, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 461, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, - 0, 461, 461, 461, 461, 461 + 469, 1, 469, 469, 469, 469, 470, 471, 472, 469, + 471, 471, 471, 471, 473, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 470, 469, 471, 469, + 474, 474, 469, 469, 471, 471, 471, 471, 471, 473, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 469, 474, 474, 469, 471, 471, 471, 49, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 49, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + + 471, 471, 469, 469, 469, 469, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 166, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 469, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 0, 469, + 469, 469, 469, 469 } ; -static yyconst short int yy_nxt[1007] = +static yyconst short int yy_nxt[1023] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 15, 8, 8, 8, 16, 17, 18, 19, @@ -550,114 +552,116 @@ 28, 8, 29, 30, 31, 32, 33, 34, 35, 8, 36, 42, 40, 43, 43, 44, 44, 45, 45, 40, 46, 87, 40, 40, 47, 48, 48, 40, 47, 48, - 48, 40, 40, 125, 40, 40, 40, 40, 40, 59, - 51, 60, 40, 160, 55, 110, 62, 52, 56, 53, + 48, 40, 40, 126, 40, 40, 40, 40, 40, 59, + 51, 60, 40, 161, 55, 110, 62, 52, 56, 53, 63, 54, 61, 57, 49, 64, 58, 40, 40, 65, 40, 40, 67, 40, 40, 40, 75, 71, 78, 66, 68, 40, 69, 72, 76, 82, 73, 74, 70, 77, 40, 40, 80, 85, 83, 40, 84, 79, 81, 86, - 88, 40, 40, 40, 112, 122, 95, 117, 89, 111, + 88, 40, 40, 122, 112, 123, 95, 117, 89, 111, 40, 90, 115, 115, 91, 43, 43, 40, 40, 96, - 114, 127, 97, 40, 130, 92, 93, 40, 94, 98, - 88, 121, 40, 116, 44, 44, 40, 124, 99, 47, - 45, 45, 40, 40, 123, 100, 40, 101, 40, 102, - 146, 118, 118, 40, 103, 40, 119, 126, 128, 40, - 104, 41, 119, 156, 105, 129, 106, 40, 107, 47, - 48, 48, 40, 108, 131, 132, 133, 109, 120, 120, - - 40, 40, 120, 120, 40, 120, 120, 120, 120, 120, - 120, 134, 136, 40, 40, 40, 40, 40, 40, 40, - 40, 138, 139, 135, 40, 137, 40, 145, 40, 141, - 40, 40, 151, 40, 40, 144, 142, 147, 140, 148, - 40, 40, 40, 143, 161, 152, 154, 149, 157, 150, - 40, 153, 40, 158, 40, 159, 40, 40, 155, 40, - 40, 165, 40, 162, 40, 173, 40, 40, 163, 167, - 166, 40, 40, 174, 172, 164, 179, 168, 40, 169, - 175, 40, 170, 181, 177, 171, 40, 40, 176, 183, - 180, 188, 189, 40, 184, 178, 182, 40, 187, 40, - - 191, 40, 185, 40, 190, 40, 192, 186, 40, 40, - 198, 40, 194, 193, 195, 196, 40, 197, 115, 115, - 202, 202, 40, 331, 199, 203, 40, 118, 118, 40, - 200, 203, 119, 40, 207, 208, 204, 205, 119, 206, - 206, 40, 40, 40, 40, 212, 209, 40, 40, 40, - 40, 40, 213, 214, 40, 40, 40, 210, 211, 40, - 218, 40, 40, 40, 216, 217, 40, 40, 219, 40, - 215, 220, 221, 223, 226, 225, 227, 40, 40, 224, - 40, 40, 40, 40, 222, 40, 228, 229, 40, 231, - 40, 40, 233, 230, 40, 40, 40, 40, 236, 234, - - 232, 40, 237, 40, 40, 40, 265, 40, 40, 238, - 239, 235, 244, 271, 241, 40, 240, 242, 242, 252, - 40, 242, 242, 40, 242, 242, 242, 242, 242, 242, - 243, 251, 245, 40, 246, 40, 249, 40, 247, 40, - 248, 250, 40, 40, 253, 40, 255, 40, 256, 40, - 40, 40, 40, 40, 254, 40, 260, 40, 262, 40, - 40, 40, 259, 40, 263, 257, 258, 261, 267, 40, - 264, 40, 40, 40, 266, 276, 270, 272, 268, 40, - 269, 277, 202, 202, 273, 40, 274, 203, 204, 204, - 280, 278, 278, 203, 275, 278, 278, 206, 206, 40, - - 206, 206, 40, 40, 40, 40, 40, 40, 284, 40, - 279, 40, 282, 40, 285, 40, 40, 40, 288, 283, - 286, 281, 291, 40, 40, 40, 287, 40, 40, 40, - 40, 293, 292, 294, 289, 297, 40, 290, 298, 40, - 40, 40, 40, 296, 40, 40, 40, 40, 40, 40, - 295, 40, 40, 300, 40, 301, 307, 299, 308, 302, - 303, 310, 304, 312, 40, 40, 305, 40, 309, 306, - 40, 40, 315, 314, 316, 311, 318, 313, 317, 40, - 40, 40, 40, 40, 40, 319, 40, 40, 320, 324, - 40, 321, 322, 40, 323, 40, 40, 40, 40, 40, - - 325, 328, 278, 278, 40, 40, 334, 326, 327, 340, - 40, 40, 339, 330, 40, 40, 40, 40, 341, 332, - 329, 333, 342, 335, 40, 336, 345, 40, 343, 337, - 346, 338, 344, 40, 348, 40, 40, 40, 40, 349, - 40, 40, 347, 351, 352, 40, 40, 353, 40, 40, - 40, 40, 350, 40, 40, 354, 40, 355, 357, 359, - 360, 40, 356, 358, 40, 361, 364, 40, 40, 40, - 362, 363, 40, 366, 365, 368, 40, 369, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 371, 40, 374, - 367, 377, 40, 40, 375, 370, 40, 379, 40, 385, - - 373, 372, 381, 378, 40, 376, 40, 383, 40, 384, - 40, 380, 40, 386, 40, 390, 382, 388, 389, 40, - 40, 40, 40, 387, 40, 394, 40, 40, 393, 395, - 392, 40, 40, 40, 40, 391, 40, 397, 398, 40, - 40, 401, 396, 40, 40, 40, 400, 403, 399, 405, - 40, 40, 40, 404, 408, 40, 402, 40, 407, 409, - 40, 410, 406, 40, 412, 414, 411, 40, 415, 40, - 40, 40, 40, 40, 413, 40, 416, 40, 417, 40, - 40, 419, 40, 426, 40, 40, 420, 421, 40, 40, - 422, 40, 418, 424, 425, 427, 40, 428, 423, 40, - - 429, 431, 433, 40, 435, 40, 40, 430, 40, 40, - 40, 40, 40, 40, 432, 40, 40, 40, 434, 440, - 40, 436, 437, 40, 442, 444, 445, 438, 443, 40, - 40, 40, 439, 447, 40, 446, 449, 40, 448, 40, - 441, 40, 40, 40, 40, 454, 40, 450, 451, 40, - 40, 40, 40, 40, 40, 452, 40, 453, 459, 40, - 40, 458, 40, 40, 40, 456, 457, 460, 40, 40, - 455, 37, 37, 37, 37, 39, 39, 50, 40, 50, - 50, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 97, 40, 131, 92, 93, 193, 94, 98, + 88, 121, 40, 116, 44, 44, 40, 125, 99, 47, + 45, 45, 40, 40, 124, 100, 40, 101, 144, 102, + 40, 118, 118, 40, 103, 40, 119, 127, 40, 40, + 104, 128, 119, 114, 105, 41, 106, 146, 107, 47, + 48, 48, 40, 108, 129, 137, 40, 109, 120, 120, + + 40, 130, 120, 120, 40, 120, 120, 120, 120, 120, + 120, 132, 133, 134, 40, 40, 40, 40, 40, 40, + 40, 135, 40, 139, 140, 40, 40, 40, 138, 40, + 40, 142, 152, 136, 155, 40, 145, 40, 143, 149, + 141, 40, 147, 148, 153, 150, 156, 151, 40, 40, + 154, 40, 157, 159, 40, 40, 158, 40, 40, 40, + 40, 40, 162, 160, 163, 168, 40, 175, 40, 40, + 164, 40, 176, 169, 40, 40, 40, 165, 174, 177, + 40, 170, 166, 171, 179, 167, 172, 178, 181, 173, + 40, 40, 183, 40, 184, 180, 40, 40, 185, 40, + + 190, 191, 182, 186, 194, 189, 40, 195, 40, 40, + 196, 187, 197, 192, 200, 198, 188, 199, 40, 115, + 115, 204, 204, 118, 118, 40, 205, 201, 119, 40, + 40, 40, 205, 40, 119, 40, 40, 206, 207, 202, + 208, 208, 40, 212, 209, 211, 213, 210, 40, 40, + 214, 40, 40, 40, 40, 40, 40, 216, 217, 40, + 40, 221, 40, 40, 40, 223, 40, 40, 219, 220, + 232, 215, 222, 218, 40, 224, 228, 40, 233, 229, + 40, 40, 226, 40, 40, 227, 230, 225, 40, 231, + 234, 40, 40, 236, 40, 40, 40, 40, 40, 40, + + 239, 235, 237, 40, 40, 240, 40, 40, 40, 40, + 241, 242, 248, 40, 238, 244, 259, 243, 245, 245, + 253, 40, 245, 245, 40, 245, 245, 245, 245, 245, + 245, 246, 247, 249, 254, 250, 40, 40, 40, 251, + 40, 252, 40, 40, 255, 40, 40, 40, 257, 260, + 40, 256, 40, 40, 40, 264, 40, 258, 269, 266, + 40, 40, 263, 40, 265, 261, 262, 267, 40, 271, + 268, 40, 40, 40, 40, 40, 275, 270, 276, 277, + 40, 40, 282, 282, 272, 40, 273, 274, 40, 283, + 278, 204, 204, 40, 280, 284, 205, 40, 279, 281, + + 206, 206, 205, 282, 282, 208, 208, 40, 208, 208, + 40, 40, 40, 40, 285, 40, 289, 40, 40, 287, + 290, 40, 40, 40, 40, 40, 288, 293, 286, 296, + 291, 40, 40, 292, 297, 40, 40, 40, 298, 40, + 294, 40, 302, 299, 295, 40, 40, 40, 303, 40, + 40, 301, 40, 40, 40, 300, 40, 40, 40, 305, + 314, 306, 304, 40, 308, 307, 312, 40, 309, 313, + 40, 40, 316, 40, 40, 40, 310, 311, 315, 318, + 320, 323, 322, 40, 324, 40, 317, 40, 40, 40, + 321, 40, 40, 319, 326, 40, 330, 328, 325, 327, + + 40, 40, 329, 40, 40, 40, 40, 40, 40, 331, + 40, 40, 334, 282, 282, 40, 332, 337, 40, 340, + 345, 333, 336, 40, 40, 40, 347, 361, 40, 338, + 335, 339, 341, 346, 342, 40, 351, 40, 343, 40, + 344, 349, 348, 352, 350, 40, 40, 40, 355, 40, + 40, 40, 40, 40, 353, 40, 357, 358, 40, 40, + 359, 40, 40, 354, 356, 366, 40, 360, 363, 40, + 362, 365, 364, 40, 40, 367, 40, 40, 368, 369, + 40, 40, 40, 40, 40, 40, 371, 40, 375, 373, + 376, 40, 40, 40, 40, 378, 370, 40, 40, 372, + + 374, 381, 40, 40, 384, 40, 377, 382, 379, 40, + 383, 386, 380, 385, 388, 391, 392, 40, 390, 40, + 40, 40, 40, 40, 40, 387, 393, 397, 389, 395, + 40, 40, 40, 40, 40, 40, 394, 401, 402, 400, + 399, 40, 40, 396, 40, 40, 398, 40, 405, 40, + 40, 404, 40, 406, 403, 40, 409, 40, 40, 408, + 40, 413, 411, 407, 40, 40, 40, 412, 410, 416, + 40, 40, 415, 417, 40, 418, 422, 40, 414, 420, + 419, 40, 423, 424, 40, 40, 40, 40, 421, 40, + 40, 40, 40, 40, 40, 40, 427, 40, 434, 40, + + 40, 428, 425, 432, 429, 40, 435, 426, 430, 433, + 431, 40, 40, 441, 436, 40, 40, 439, 438, 40, + 437, 443, 40, 40, 40, 40, 440, 40, 449, 40, + 442, 40, 40, 40, 448, 444, 450, 40, 445, 40, + 452, 453, 446, 40, 451, 40, 40, 447, 456, 40, + 455, 40, 40, 40, 40, 40, 454, 40, 457, 40, + 458, 462, 40, 459, 40, 40, 40, 40, 467, 461, + 460, 40, 40, 40, 466, 40, 40, 464, 465, 40, + 40, 463, 40, 468, 37, 37, 37, 37, 39, 39, + 50, 40, 50, 50, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 201, 40, 40, 40, 40, 40, - 113, 40, 38, 461, 3, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - - 461, 461, 461, 461, 461, 461 + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 203, 40, 40, 40, 40, 40, 113, 40, 38, 469, + 3, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469 } ; -static yyconst short int yy_chk[1007] = +static yyconst short int yy_chk[1023] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -672,104 +676,106 @@ 21, 28, 21, 22, 24, 27, 23, 23, 21, 24, 52, 35, 26, 28, 27, 36, 27, 25, 26, 28, - 30, 31, 30, 57, 36, 52, 31, 46, 30, 35, + 30, 31, 30, 52, 36, 52, 31, 46, 30, 35, 46, 30, 42, 42, 30, 43, 43, 60, 54, 31, - 466, 57, 31, 51, 60, 30, 30, 71, 30, 31, + 105, 68, 31, 51, 60, 30, 30, 105, 30, 31, 32, 51, 32, 44, 44, 44, 53, 54, 32, 45, - 45, 45, 45, 59, 53, 32, 56, 32, 78, 32, - 71, 47, 47, 47, 32, 33, 47, 56, 59, 61, - 33, 464, 47, 78, 33, 59, 33, 63, 33, 48, - 48, 48, 48, 33, 61, 61, 61, 33, 49, 49, - - 49, 64, 49, 49, 62, 49, 49, 49, 49, 49, - 49, 62, 63, 65, 67, 66, 68, 69, 70, 72, - 73, 65, 66, 62, 74, 64, 75, 70, 76, 67, - 80, 85, 75, 79, 88, 69, 67, 72, 66, 73, - 81, 77, 89, 68, 85, 76, 77, 74, 79, 74, - 86, 76, 87, 80, 90, 81, 92, 98, 77, 93, - 94, 88, 99, 86, 91, 93, 100, 95, 87, 90, - 89, 97, 460, 94, 92, 87, 98, 90, 101, 91, - 95, 102, 91, 100, 97, 91, 103, 104, 95, 102, - 99, 104, 104, 105, 102, 97, 101, 107, 103, 108, - - 105, 106, 102, 111, 104, 110, 106, 102, 109, 112, - 110, 269, 108, 107, 108, 109, 122, 109, 115, 115, - 116, 116, 129, 269, 111, 116, 124, 118, 118, 118, - 112, 116, 118, 125, 122, 124, 119, 119, 118, 119, - 119, 119, 127, 128, 131, 129, 125, 132, 133, 134, - 135, 141, 131, 132, 137, 138, 142, 127, 128, 458, - 137, 457, 139, 140, 134, 135, 143, 145, 138, 144, - 133, 139, 140, 141, 144, 143, 145, 146, 148, 142, - 149, 147, 150, 151, 140, 152, 146, 147, 153, 149, - 154, 155, 151, 148, 156, 159, 160, 162, 154, 152, - - 150, 188, 155, 167, 175, 194, 188, 166, 174, 156, - 159, 153, 167, 194, 162, 170, 160, 165, 165, 175, - 172, 165, 165, 168, 165, 165, 165, 165, 165, 165, - 166, 174, 168, 176, 168, 177, 170, 178, 168, 179, - 168, 172, 180, 181, 176, 182, 178, 183, 179, 185, - 184, 186, 187, 189, 177, 191, 183, 192, 185, 190, - 193, 198, 182, 200, 186, 180, 181, 184, 190, 456, - 187, 197, 195, 208, 189, 198, 193, 195, 191, 196, - 192, 200, 202, 202, 196, 215, 197, 202, 203, 203, - 208, 203, 203, 202, 197, 204, 204, 205, 205, 205, - - 206, 206, 206, 207, 209, 213, 214, 217, 215, 216, - 207, 218, 213, 219, 216, 220, 221, 222, 219, 214, - 217, 209, 222, 223, 224, 225, 218, 226, 228, 230, - 229, 224, 223, 225, 220, 229, 231, 221, 230, 232, - 233, 234, 240, 228, 238, 235, 241, 243, 245, 249, - 226, 244, 246, 232, 247, 233, 243, 231, 244, 234, - 235, 246, 238, 247, 248, 250, 240, 253, 245, 241, - 254, 251, 249, 248, 250, 246, 253, 247, 251, 257, - 259, 261, 260, 263, 262, 254, 264, 265, 257, 262, - 266, 259, 260, 267, 261, 268, 272, 274, 273, 277, - - 263, 266, 278, 278, 279, 285, 274, 264, 265, 279, - 280, 283, 277, 268, 275, 282, 289, 288, 280, 272, - 267, 273, 282, 275, 286, 275, 285, 284, 283, 275, - 286, 275, 284, 287, 288, 290, 291, 293, 296, 289, - 297, 298, 287, 291, 293, 299, 302, 296, 308, 300, - 303, 318, 290, 304, 317, 297, 305, 298, 300, 303, - 304, 306, 299, 302, 319, 305, 317, 323, 324, 325, - 306, 308, 326, 319, 318, 324, 327, 325, 329, 330, - 331, 332, 333, 335, 334, 454, 341, 327, 336, 331, - 323, 334, 339, 337, 332, 326, 346, 336, 338, 341, - - 330, 329, 337, 335, 343, 333, 344, 338, 345, 339, - 350, 336, 351, 343, 353, 350, 337, 345, 346, 355, - 356, 362, 358, 344, 367, 356, 368, 374, 355, 358, - 353, 375, 376, 377, 384, 351, 385, 367, 368, 387, - 386, 376, 362, 390, 393, 391, 375, 384, 374, 386, - 392, 394, 396, 385, 391, 395, 377, 401, 390, 392, - 397, 393, 387, 398, 395, 397, 394, 400, 398, 403, - 404, 405, 408, 409, 396, 410, 400, 415, 401, 414, - 413, 404, 418, 415, 422, 424, 405, 408, 420, 425, - 409, 421, 403, 413, 414, 418, 423, 420, 410, 427, - - 421, 423, 425, 426, 427, 428, 429, 422, 430, 431, - 432, 433, 438, 435, 424, 434, 436, 437, 426, 432, - 439, 428, 429, 443, 434, 436, 437, 430, 435, 441, - 444, 445, 431, 439, 446, 438, 443, 448, 441, 447, - 433, 449, 450, 451, 453, 448, 459, 444, 445, 455, - 452, 442, 440, 419, 417, 446, 416, 447, 455, 412, - 411, 453, 407, 406, 402, 450, 451, 459, 399, 389, - 449, 462, 462, 462, 462, 463, 463, 465, 388, 465, - 465, 383, 382, 381, 380, 379, 378, 373, 372, 371, - 370, 369, 366, 365, 364, 363, 361, 360, 359, 357, - - 354, 352, 349, 348, 347, 342, 340, 328, 322, 321, - 320, 316, 315, 314, 313, 312, 311, 310, 309, 307, - 301, 295, 294, 292, 281, 276, 271, 270, 258, 256, - 255, 252, 239, 237, 236, 227, 212, 211, 210, 199, - 173, 171, 169, 164, 163, 161, 158, 157, 136, 130, - 126, 123, 121, 117, 113, 96, 84, 82, 58, 39, - 37, 8, 7, 3, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - - 461, 461, 461, 461, 461, 461 + 45, 45, 45, 57, 53, 32, 56, 32, 68, 32, + 63, 47, 47, 47, 32, 33, 47, 56, 70, 59, + 33, 57, 47, 474, 33, 472, 33, 70, 33, 48, + 48, 48, 48, 33, 59, 63, 61, 33, 49, 49, + + 49, 59, 49, 49, 64, 49, 49, 49, 49, 49, + 49, 61, 61, 61, 62, 65, 67, 66, 69, 71, + 73, 62, 74, 65, 66, 72, 75, 76, 64, 77, + 80, 67, 75, 62, 77, 468, 69, 78, 67, 73, + 66, 79, 71, 72, 76, 74, 77, 74, 81, 85, + 76, 86, 78, 80, 87, 88, 79, 89, 90, 94, + 92, 93, 85, 81, 86, 90, 95, 93, 91, 98, + 87, 97, 94, 90, 99, 100, 101, 87, 92, 95, + 466, 90, 88, 91, 97, 89, 91, 95, 98, 91, + 102, 107, 100, 103, 101, 97, 104, 108, 102, 106, + + 104, 104, 99, 102, 106, 103, 111, 107, 109, 110, + 108, 102, 108, 104, 110, 109, 102, 109, 112, 115, + 115, 116, 116, 118, 118, 118, 116, 111, 118, 123, + 126, 128, 116, 122, 118, 129, 125, 119, 119, 112, + 119, 119, 119, 126, 122, 125, 128, 123, 130, 132, + 129, 134, 133, 135, 136, 138, 140, 132, 133, 139, + 142, 138, 143, 149, 148, 140, 141, 144, 135, 136, + 148, 130, 139, 134, 145, 141, 144, 146, 149, 145, + 147, 150, 142, 151, 152, 143, 146, 141, 153, 147, + 150, 154, 155, 152, 156, 157, 160, 161, 163, 172, + + 155, 151, 153, 169, 465, 156, 464, 180, 167, 168, + 157, 160, 169, 174, 154, 163, 180, 161, 166, 166, + 172, 176, 166, 166, 170, 166, 166, 166, 166, 166, + 166, 167, 168, 170, 174, 170, 177, 178, 179, 170, + 181, 170, 182, 183, 176, 184, 185, 186, 178, 181, + 187, 177, 189, 190, 188, 185, 191, 179, 190, 187, + 192, 193, 184, 194, 186, 182, 183, 188, 196, 192, + 189, 195, 209, 197, 198, 199, 196, 191, 197, 198, + 200, 202, 206, 206, 193, 462, 194, 195, 210, 209, + 199, 204, 204, 218, 200, 210, 204, 211, 199, 202, + + 205, 205, 204, 205, 205, 207, 207, 207, 208, 208, + 208, 212, 216, 217, 211, 219, 218, 220, 221, 216, + 219, 223, 222, 224, 225, 226, 217, 222, 212, 225, + 220, 227, 229, 221, 226, 228, 231, 232, 227, 233, + 223, 234, 232, 228, 224, 235, 236, 237, 233, 238, + 241, 231, 243, 248, 244, 229, 247, 246, 249, 235, + 248, 236, 234, 250, 238, 237, 246, 253, 241, 247, + 251, 252, 250, 254, 255, 257, 243, 244, 249, 251, + 252, 255, 254, 258, 257, 261, 250, 264, 263, 265, + 253, 266, 267, 251, 261, 268, 266, 264, 258, 263, + + 269, 270, 265, 271, 272, 273, 276, 281, 277, 267, + 278, 303, 270, 282, 282, 290, 268, 273, 285, 278, + 281, 269, 272, 279, 288, 294, 285, 303, 284, 276, + 271, 277, 279, 284, 279, 287, 290, 291, 279, 289, + 279, 288, 287, 291, 289, 292, 293, 295, 294, 296, + 298, 301, 302, 304, 292, 307, 296, 298, 309, 305, + 301, 313, 308, 293, 295, 309, 310, 302, 305, 311, + 304, 308, 307, 314, 323, 310, 324, 329, 311, 313, + 325, 330, 331, 332, 333, 335, 323, 339, 330, 325, + 331, 336, 337, 341, 338, 333, 314, 340, 345, 324, + + 329, 337, 342, 347, 340, 343, 332, 338, 335, 344, + 339, 342, 336, 341, 343, 345, 347, 349, 344, 350, + 351, 352, 356, 357, 359, 342, 349, 356, 343, 351, + 361, 364, 362, 368, 369, 374, 350, 362, 364, 361, + 359, 375, 381, 352, 382, 384, 357, 383, 374, 391, + 392, 369, 393, 375, 368, 394, 383, 397, 400, 382, + 398, 393, 391, 381, 399, 401, 403, 392, 384, 398, + 402, 405, 397, 399, 408, 400, 405, 406, 394, 402, + 401, 409, 406, 408, 411, 412, 413, 418, 403, 416, + 421, 417, 423, 426, 422, 430, 412, 432, 423, 441, + + 433, 413, 409, 421, 416, 428, 426, 411, 417, 422, + 418, 429, 431, 433, 428, 434, 435, 431, 430, 436, + 429, 435, 437, 438, 439, 440, 432, 442, 441, 443, + 434, 444, 445, 446, 440, 436, 442, 447, 437, 449, + 444, 445, 438, 452, 443, 451, 453, 439, 449, 454, + 447, 455, 457, 456, 458, 459, 446, 461, 451, 463, + 452, 456, 467, 453, 460, 450, 448, 427, 463, 455, + 454, 425, 424, 420, 461, 419, 415, 458, 459, 414, + 410, 457, 407, 467, 470, 470, 470, 470, 471, 471, + 473, 404, 473, 473, 396, 395, 390, 389, 388, 387, + + 386, 385, 380, 379, 378, 377, 376, 373, 372, 371, + 370, 367, 366, 365, 363, 360, 358, 355, 354, 353, + 348, 346, 334, 328, 327, 326, 322, 321, 320, 319, + 318, 317, 316, 315, 312, 306, 300, 299, 297, 286, + 283, 280, 275, 274, 262, 260, 259, 256, 242, 240, + 239, 230, 215, 214, 213, 201, 175, 173, 171, 165, + 164, 162, 159, 158, 137, 131, 127, 124, 121, 117, + 113, 96, 84, 82, 58, 39, 37, 8, 7, 3, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469 } ; static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr; @@ -786,7 +792,7 @@ #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; -#line 1 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 1 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" #define INITIAL 0 /*===-- Lexer.l - Scanner for llvm assembly files --------------*- C++ -*--===// // @@ -801,7 +807,7 @@ // //===----------------------------------------------------------------------===*/ #define YY_NEVER_INTERACTIVE 1 -#line 28 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 28 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" #include "ParserInternals.h" #include "llvm/Module.h" #include @@ -927,7 +933,7 @@ /* HexIntConstant - Hexadecimal constant generated by the CFE to avoid forcing * it to deal with 64 bit numbers. */ -#line 931 "Lexer.cpp" +#line 937 "Lexer.cpp" /* Macros after this point can all be overridden by user definitions in * section 1. @@ -1075,13 +1081,13 @@ YY_DECL { register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; + register char *yy_cp = NULL, *yy_bp = NULL; register int yy_act; -#line 179 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 179 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" -#line 1085 "Lexer.cpp" +#line 1091 "Lexer.cpp" if ( yy_init ) { @@ -1129,14 +1135,14 @@ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 462 ) + if ( yy_current_state >= 470 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; *yy_state_ptr++ = yy_current_state; ++yy_cp; } - while ( yy_current_state != 461 ); + while ( yy_current_state != 469 ); yy_find_action: yy_current_state = *--yy_state_ptr; @@ -1174,526 +1180,536 @@ { /* beginning of action switch */ case 1: YY_RULE_SETUP -#line 181 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 181 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { /* Ignore comments for now */ } YY_BREAK case 2: YY_RULE_SETUP -#line 183 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 183 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return BEGINTOK; } YY_BREAK case 3: YY_RULE_SETUP -#line 184 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 184 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return ENDTOK; } YY_BREAK case 4: YY_RULE_SETUP -#line 185 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 185 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return TRUETOK; } YY_BREAK case 5: YY_RULE_SETUP -#line 186 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 186 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return FALSETOK; } YY_BREAK case 6: YY_RULE_SETUP -#line 187 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 187 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return DECLARE; } YY_BREAK case 7: YY_RULE_SETUP -#line 188 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 188 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return GLOBAL; } YY_BREAK case 8: YY_RULE_SETUP -#line 189 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 189 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return CONSTANT; } YY_BREAK case 9: YY_RULE_SETUP -#line 190 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 190 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return INTERNAL; } YY_BREAK case 10: YY_RULE_SETUP -#line 191 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 191 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return LINKONCE; } YY_BREAK case 11: YY_RULE_SETUP -#line 192 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 192 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return WEAK; } YY_BREAK case 12: YY_RULE_SETUP -#line 193 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 193 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return APPENDING; } YY_BREAK case 13: YY_RULE_SETUP -#line 194 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 194 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return EXTERNAL; } /* Deprecated, turn into external */ YY_BREAK case 14: YY_RULE_SETUP -#line 195 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 195 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return EXTERNAL; } YY_BREAK case 15: YY_RULE_SETUP -#line 196 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 196 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return IMPLEMENTATION; } YY_BREAK case 16: YY_RULE_SETUP -#line 197 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 197 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return ZEROINITIALIZER; } YY_BREAK case 17: YY_RULE_SETUP -#line 198 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 198 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return DOTDOTDOT; } YY_BREAK case 18: YY_RULE_SETUP -#line 199 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 199 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return UNDEF; } YY_BREAK case 19: YY_RULE_SETUP -#line 200 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 200 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return NULL_TOK; } YY_BREAK case 20: YY_RULE_SETUP -#line 201 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 201 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return TO; } YY_BREAK case 21: YY_RULE_SETUP -#line 202 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 202 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { RET_TOK(TermOpVal, Unwind, UNWIND); } YY_BREAK case 22: YY_RULE_SETUP -#line 203 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 203 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return NOT; } /* Deprecated, turned into XOR */ YY_BREAK case 23: YY_RULE_SETUP -#line 204 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 204 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return TAIL; } YY_BREAK case 24: YY_RULE_SETUP -#line 205 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 205 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return TARGET; } YY_BREAK case 25: YY_RULE_SETUP -#line 206 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 206 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return TRIPLE; } YY_BREAK case 26: YY_RULE_SETUP -#line 207 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 207 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return DEPLIBS; } YY_BREAK case 27: YY_RULE_SETUP -#line 208 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 208 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return ENDIAN; } YY_BREAK case 28: YY_RULE_SETUP -#line 209 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 209 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return POINTERSIZE; } YY_BREAK case 29: YY_RULE_SETUP -#line 210 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 210 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return LITTLE; } YY_BREAK case 30: YY_RULE_SETUP -#line 211 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 211 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return BIG; } YY_BREAK case 31: YY_RULE_SETUP -#line 212 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 212 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return VOLATILE; } YY_BREAK case 32: YY_RULE_SETUP -#line 213 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 213 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return FIXED; } YY_BREAK case 33: YY_RULE_SETUP -#line 215 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ return CC_TOK; } +#line 214 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ return ALIGN; } YY_BREAK case 34: YY_RULE_SETUP -#line 216 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ return CCC_TOK; } +#line 215 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ return SECTION; } YY_BREAK case 35: YY_RULE_SETUP -#line 217 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ return FASTCC_TOK; } +#line 217 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ return CC_TOK; } YY_BREAK case 36: YY_RULE_SETUP -#line 218 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ return COLDCC_TOK; } +#line 218 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ return CCC_TOK; } YY_BREAK case 37: YY_RULE_SETUP -#line 220 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::VoidTy ; return VOID; } +#line 219 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ return FASTCC_TOK; } YY_BREAK case 38: YY_RULE_SETUP -#line 221 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::BoolTy ; return BOOL; } +#line 220 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ return COLDCC_TOK; } YY_BREAK case 39: YY_RULE_SETUP -#line 222 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::SByteTy ; return SBYTE; } +#line 222 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ llvmAsmlval.PrimType = Type::VoidTy ; return VOID; } YY_BREAK case 40: YY_RULE_SETUP -#line 223 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::UByteTy ; return UBYTE; } +#line 223 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ llvmAsmlval.PrimType = Type::BoolTy ; return BOOL; } YY_BREAK case 41: YY_RULE_SETUP -#line 224 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::ShortTy ; return SHORT; } +#line 224 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ llvmAsmlval.PrimType = Type::SByteTy ; return SBYTE; } YY_BREAK case 42: YY_RULE_SETUP -#line 225 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::UShortTy; return USHORT; } +#line 225 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ llvmAsmlval.PrimType = Type::UByteTy ; return UBYTE; } YY_BREAK case 43: YY_RULE_SETUP -#line 226 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::IntTy ; return INT; } +#line 226 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ llvmAsmlval.PrimType = Type::ShortTy ; return SHORT; } YY_BREAK case 44: YY_RULE_SETUP -#line 227 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::UIntTy ; return UINT; } +#line 227 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ llvmAsmlval.PrimType = Type::UShortTy; return USHORT; } YY_BREAK case 45: YY_RULE_SETUP -#line 228 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::LongTy ; return LONG; } +#line 228 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ llvmAsmlval.PrimType = Type::IntTy ; return INT; } YY_BREAK case 46: YY_RULE_SETUP -#line 229 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::ULongTy ; return ULONG; } +#line 229 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ llvmAsmlval.PrimType = Type::UIntTy ; return UINT; } YY_BREAK case 47: YY_RULE_SETUP -#line 230 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::FloatTy ; return FLOAT; } +#line 230 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ llvmAsmlval.PrimType = Type::LongTy ; return LONG; } YY_BREAK case 48: YY_RULE_SETUP -#line 231 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::DoubleTy; return DOUBLE; } +#line 231 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ llvmAsmlval.PrimType = Type::ULongTy ; return ULONG; } YY_BREAK case 49: YY_RULE_SETUP -#line 232 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ llvmAsmlval.PrimType = Type::LabelTy ; return LABEL; } +#line 232 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ llvmAsmlval.PrimType = Type::FloatTy ; return FLOAT; } YY_BREAK case 50: YY_RULE_SETUP -#line 233 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ return TYPE; } +#line 233 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ llvmAsmlval.PrimType = Type::DoubleTy; return DOUBLE; } YY_BREAK case 51: YY_RULE_SETUP -#line 234 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ return OPAQUE; } +#line 234 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ llvmAsmlval.PrimType = Type::LabelTy ; return LABEL; } YY_BREAK case 52: YY_RULE_SETUP -#line 236 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, Add, ADD); } +#line 235 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ return TYPE; } YY_BREAK case 53: YY_RULE_SETUP -#line 237 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, Sub, SUB); } +#line 236 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ return OPAQUE; } YY_BREAK case 54: YY_RULE_SETUP -#line 238 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, Mul, MUL); } +#line 238 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, Add, ADD); } YY_BREAK case 55: YY_RULE_SETUP -#line 239 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, Div, DIV); } +#line 239 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, Sub, SUB); } YY_BREAK case 56: YY_RULE_SETUP -#line 240 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, Rem, REM); } +#line 240 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, Mul, MUL); } YY_BREAK case 57: YY_RULE_SETUP -#line 241 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, And, AND); } +#line 241 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, Div, DIV); } YY_BREAK case 58: YY_RULE_SETUP -#line 242 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, Or , OR ); } +#line 242 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, Rem, REM); } YY_BREAK case 59: YY_RULE_SETUP -#line 243 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, Xor, XOR); } +#line 243 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, And, AND); } YY_BREAK case 60: YY_RULE_SETUP -#line 244 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, SetNE, SETNE); } +#line 244 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, Or , OR ); } YY_BREAK case 61: YY_RULE_SETUP -#line 245 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, SetEQ, SETEQ); } +#line 245 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, Xor, XOR); } YY_BREAK case 62: YY_RULE_SETUP -#line 246 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, SetLT, SETLT); } +#line 246 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, SetNE, SETNE); } YY_BREAK case 63: YY_RULE_SETUP -#line 247 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, SetGT, SETGT); } +#line 247 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, SetEQ, SETEQ); } YY_BREAK case 64: YY_RULE_SETUP -#line 248 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, SetLE, SETLE); } +#line 248 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, SetLT, SETLT); } YY_BREAK case 65: YY_RULE_SETUP -#line 249 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, SetGE, SETGE); } +#line 249 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, SetGT, SETGT); } YY_BREAK case 66: YY_RULE_SETUP -#line 250 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, VSetNE, VSETNE); } +#line 250 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, SetLE, SETLE); } YY_BREAK case 67: YY_RULE_SETUP -#line 251 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, VSetEQ, VSETEQ); } +#line 251 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, SetGE, SETGE); } YY_BREAK case 68: YY_RULE_SETUP -#line 252 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, VSetLT, VSETLT); } +#line 252 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, VSetNE, VSETNE); } YY_BREAK case 69: YY_RULE_SETUP -#line 253 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, VSetGT, VSETGT); } +#line 253 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, VSetEQ, VSETEQ); } YY_BREAK case 70: YY_RULE_SETUP -#line 254 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, VSetLE, VSETLE); } +#line 254 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, VSetLT, VSETLT); } YY_BREAK case 71: YY_RULE_SETUP -#line 255 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(BinaryOpVal, VSetGE, VSETGE); } +#line 255 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, VSetGT, VSETGT); } YY_BREAK case 72: YY_RULE_SETUP -#line 257 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, PHI, PHI_TOK); } +#line 256 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, VSetLE, VSETLE); } YY_BREAK case 73: YY_RULE_SETUP -#line 258 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, Call, CALL); } +#line 257 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(BinaryOpVal, VSetGE, VSETGE); } YY_BREAK case 74: YY_RULE_SETUP -#line 259 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, Cast, CAST); } +#line 259 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, PHI, PHI_TOK); } YY_BREAK case 75: YY_RULE_SETUP -#line 260 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, Select, SELECT); } +#line 260 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, Call, CALL); } YY_BREAK case 76: YY_RULE_SETUP -#line 261 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, VSelect, VSELECT); } +#line 261 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, Cast, CAST); } YY_BREAK case 77: YY_RULE_SETUP -#line 262 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, Shl, SHL); } +#line 262 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, Select, SELECT); } YY_BREAK case 78: YY_RULE_SETUP -#line 263 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, Shr, SHR); } +#line 263 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, VSelect, VSELECT); } YY_BREAK case 79: YY_RULE_SETUP -#line 264 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ return VANEXT_old; } +#line 264 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, Shl, SHL); } YY_BREAK case 80: YY_RULE_SETUP -#line 265 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ return VAARG_old; } +#line 265 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, Shr, SHR); } YY_BREAK case 81: YY_RULE_SETUP -#line 266 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, VAArg , VAARG); } +#line 266 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ return VANEXT_old; } YY_BREAK case 82: YY_RULE_SETUP -#line 267 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(TermOpVal, Ret, RET); } +#line 267 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ return VAARG_old; } YY_BREAK case 83: YY_RULE_SETUP -#line 268 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(TermOpVal, Br, BR); } +#line 268 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, VAArg , VAARG); } YY_BREAK case 84: YY_RULE_SETUP -#line 269 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(TermOpVal, Switch, SWITCH); } +#line 269 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(TermOpVal, Ret, RET); } YY_BREAK case 85: YY_RULE_SETUP -#line 270 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(TermOpVal, Invoke, INVOKE); } +#line 270 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(TermOpVal, Br, BR); } YY_BREAK case 86: YY_RULE_SETUP -#line 271 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(TermOpVal, Unwind, UNWIND); } +#line 271 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(TermOpVal, Switch, SWITCH); } YY_BREAK case 87: YY_RULE_SETUP -#line 272 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(TermOpVal, Unreachable, UNREACHABLE); } +#line 272 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(TermOpVal, Invoke, INVOKE); } YY_BREAK case 88: YY_RULE_SETUP -#line 274 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(MemOpVal, Malloc, MALLOC); } +#line 273 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(TermOpVal, Unwind, UNWIND); } YY_BREAK case 89: YY_RULE_SETUP -#line 275 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(MemOpVal, Alloca, ALLOCA); } +#line 274 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(TermOpVal, Unreachable, UNREACHABLE); } YY_BREAK case 90: YY_RULE_SETUP -#line 276 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(MemOpVal, Free, FREE); } +#line 276 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(MemOpVal, Malloc, MALLOC); } YY_BREAK case 91: YY_RULE_SETUP -#line 277 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(MemOpVal, Load, LOAD); } +#line 277 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(MemOpVal, Alloca, ALLOCA); } YY_BREAK case 92: YY_RULE_SETUP -#line 278 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(MemOpVal, Store, STORE); } +#line 278 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(MemOpVal, Free, FREE); } YY_BREAK case 93: YY_RULE_SETUP -#line 279 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(MemOpVal, GetElementPtr, GETELEMENTPTR); } +#line 279 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(MemOpVal, Load, LOAD); } YY_BREAK case 94: YY_RULE_SETUP -#line 280 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(MemOpVal, VGather, VGATHER); } +#line 280 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(MemOpVal, Store, STORE); } YY_BREAK case 95: YY_RULE_SETUP -#line 281 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(MemOpVal, VImm, VIMM); } +#line 281 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(MemOpVal, GetElementPtr, GETELEMENTPTR); } YY_BREAK case 96: YY_RULE_SETUP -#line 282 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(MemOpVal, VScatter, VSCATTER); } +#line 282 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(MemOpVal, VGather, VGATHER); } YY_BREAK case 97: YY_RULE_SETUP -#line 284 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, Extract, EXTRACT); } +#line 283 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(MemOpVal, VImm, VIMM); } YY_BREAK case 98: YY_RULE_SETUP -#line 285 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, ExtractElement, EXTRACTELEMENT); } +#line 284 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(MemOpVal, VScatter, VSCATTER); } YY_BREAK case 99: YY_RULE_SETUP -#line 286 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, Combine, COMBINE); } +#line 286 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, Extract, EXTRACT); } YY_BREAK case 100: YY_RULE_SETUP -#line 287 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ RET_TOK(OtherOpVal, CombineElement, COMBINEELEMENT); } +#line 287 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, ExtractElement, EXTRACTELEMENT); } YY_BREAK case 101: YY_RULE_SETUP -#line 288 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ return VECTOR; } +#line 288 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, Combine, COMBINE); } YY_BREAK case 102: YY_RULE_SETUP -#line 289 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" -{ return OF; } +#line 289 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ RET_TOK(OtherOpVal, CombineElement, COMBINEELEMENT); } YY_BREAK case 103: YY_RULE_SETUP -#line 291 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 290 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ return VECTOR; } + YY_BREAK +case 104: +YY_RULE_SETUP +#line 291 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" +{ return OF; } + YY_BREAK +case 105: +YY_RULE_SETUP +#line 293 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { UnEscapeLexed(yytext+1); llvmAsmlval.StrVal = strdup(yytext+1); // Skip % return VAR_ID; } YY_BREAK -case 104: +case 106: YY_RULE_SETUP -#line 296 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 298 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { yytext[strlen(yytext)-1] = 0; // nuke colon UnEscapeLexed(yytext); @@ -1701,9 +1717,9 @@ return LABELSTR; } YY_BREAK -case 105: +case 107: YY_RULE_SETUP -#line 302 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 304 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { yytext[strlen(yytext)-2] = 0; // nuke colon, end quote UnEscapeLexed(yytext+1); @@ -1711,9 +1727,9 @@ return LABELSTR; } YY_BREAK -case 106: +case 108: YY_RULE_SETUP -#line 309 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 311 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { // Note that we cannot unescape a string constant here! The // string constant might contain a \00 which would not be // understood by the string stuff. It is valid to make a @@ -1724,14 +1740,14 @@ return STRINGCONSTANT; } YY_BREAK -case 107: +case 109: YY_RULE_SETUP -#line 320 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 322 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { llvmAsmlval.UInt64Val = atoull(yytext); return EUINT64VAL; } YY_BREAK -case 108: +case 110: YY_RULE_SETUP -#line 321 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 323 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { uint64_t Val = atoull(yytext+1); // +1: we have bigger negative range @@ -1741,17 +1757,17 @@ return ESINT64VAL; } YY_BREAK -case 109: +case 111: YY_RULE_SETUP -#line 329 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 331 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { llvmAsmlval.UInt64Val = HexIntToVal(yytext+3); return yytext[0] == 's' ? ESINT64VAL : EUINT64VAL; } YY_BREAK -case 110: +case 112: YY_RULE_SETUP -#line 334 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 336 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { uint64_t Val = atoull(yytext+1); if ((unsigned)Val != Val) @@ -1760,9 +1776,9 @@ return UINTVAL; } YY_BREAK -case 111: +case 113: YY_RULE_SETUP -#line 341 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 343 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { uint64_t Val = atoull(yytext+2); // +1: we have bigger negative range @@ -1772,18 +1788,18 @@ return SINTVAL; } YY_BREAK -case 112: +case 114: YY_RULE_SETUP -#line 350 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 352 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { llvmAsmlval.FPVal = atof(yytext); return FPVAL; } YY_BREAK -case 113: +case 115: YY_RULE_SETUP -#line 351 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 353 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { llvmAsmlval.FPVal = HexToFP(yytext); return FPVAL; } YY_BREAK case YY_STATE_EOF(INITIAL): -#line 353 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 355 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { /* Make sure to free the internal buffers for flex when we are * done reading our input! @@ -1792,22 +1808,22 @@ return EOF; } YY_BREAK -case 114: +case 116: YY_RULE_SETUP -#line 361 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 363 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { /* Ignore whitespace */ } YY_BREAK -case 115: +case 117: YY_RULE_SETUP -#line 362 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 364 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" { return yytext[0]; } YY_BREAK -case 116: +case 118: YY_RULE_SETUP -#line 364 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 366 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1811 "Lexer.cpp" +#line 1827 "Lexer.cpp" case YY_END_OF_BUFFER: { @@ -2094,7 +2110,7 @@ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 462 ) + if ( yy_current_state >= 470 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -2124,11 +2140,11 @@ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 462 ) + if ( yy_current_state >= 470 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 461); + yy_is_jam = (yy_current_state == 469); if ( ! yy_is_jam ) *yy_state_ptr++ = yy_current_state; @@ -2183,6 +2199,7 @@ #endif /* ifndef YY_NO_UNPUT */ +#ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput() #else @@ -2256,7 +2273,7 @@ return c; } - +#endif /* YY_NO_INPUT */ #ifdef YY_USE_PROTOS void yyrestart( FILE *input_file ) @@ -2367,11 +2384,6 @@ } -#ifndef YY_ALWAYS_INTERACTIVE -#ifndef YY_NEVER_INTERACTIVE -extern int isatty YY_PROTO(( int )); -#endif -#endif #ifdef YY_USE_PROTOS void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) @@ -2689,5 +2701,5 @@ return 0; } #endif -#line 364 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/Lexer.l" +#line 366 "/home/vadve/bocchino/llvm/src/lib/AsmParser/Lexer.l" Index: llvm/lib/AsmParser/Lexer.l diff -u llvm/lib/AsmParser/Lexer.l:1.64.2.1 llvm/lib/AsmParser/Lexer.l:1.64.2.2 --- llvm/lib/AsmParser/Lexer.l:1.64.2.1 Tue Oct 18 14:21:56 2005 +++ llvm/lib/AsmParser/Lexer.l Wed Nov 16 12:32:08 2005 @@ -211,6 +211,8 @@ big { return BIG; } volatile { return VOLATILE; } fixed { return FIXED; } +align { return ALIGN; } +section { return SECTION; } cc { return CC_TOK; } ccc { return CCC_TOK; } Index: llvm/lib/AsmParser/llvmAsmParser.cpp diff -u llvm/lib/AsmParser/llvmAsmParser.cpp:1.17.2.1 llvm/lib/AsmParser/llvmAsmParser.cpp:1.17.2.2 --- llvm/lib/AsmParser/llvmAsmParser.cpp:1.17.2.1 Tue Oct 18 14:21:56 2005 +++ llvm/lib/AsmParser/llvmAsmParser.cpp Wed Nov 16 12:32:08 2005 @@ -1,126 +1,295 @@ +/* A Bison parser, made by GNU Bison 1.875. */ -/* A Bison parser, made from /Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y - by GNU Bison version 1.28 */ +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. -#define YYBISON 1 /* Identify Bison output. */ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + +/* If NAME_PREFIX is specified substitute the variables and functions + names. */ #define yyparse llvmAsmparse -#define yylex llvmAsmlex +#define yylex llvmAsmlex #define yyerror llvmAsmerror -#define yylval llvmAsmlval -#define yychar llvmAsmchar +#define yylval llvmAsmlval +#define yychar llvmAsmchar #define yydebug llvmAsmdebug #define yynerrs llvmAsmnerrs -#define ESINT64VAL 257 -#define EUINT64VAL 258 -#define SINTVAL 259 -#define UINTVAL 260 -#define FPVAL 261 -#define VOID 262 -#define BOOL 263 -#define SBYTE 264 -#define UBYTE 265 -#define SHORT 266 -#define USHORT 267 -#define INT 268 -#define UINT 269 -#define LONG 270 -#define ULONG 271 -#define FLOAT 272 -#define DOUBLE 273 -#define TYPE 274 -#define LABEL 275 -#define VAR_ID 276 -#define LABELSTR 277 -#define STRINGCONSTANT 278 -#define IMPLEMENTATION 279 -#define ZEROINITIALIZER 280 -#define TRUETOK 281 -#define FALSETOK 282 -#define BEGINTOK 283 -#define ENDTOK 284 -#define DECLARE 285 -#define GLOBAL 286 -#define CONSTANT 287 -#define VOLATILE 288 -#define FIXED 289 -#define TO 290 -#define DOTDOTDOT 291 -#define NULL_TOK 292 -#define UNDEF 293 -#define CONST 294 -#define INTERNAL 295 -#define LINKONCE 296 -#define WEAK 297 -#define APPENDING 298 -#define OPAQUE 299 -#define NOT 300 -#define EXTERNAL 301 -#define TARGET 302 -#define TRIPLE 303 -#define ENDIAN 304 -#define POINTERSIZE 305 -#define LITTLE 306 -#define BIG 307 -#define DEPLIBS 308 -#define CALL 309 -#define TAIL 310 -#define CC_TOK 311 -#define CCC_TOK 312 -#define FASTCC_TOK 313 -#define COLDCC_TOK 314 -#define VECTOR 315 -#define OF 316 -#define RET 317 -#define BR 318 -#define SWITCH 319 -#define INVOKE 320 -#define UNWIND 321 -#define UNREACHABLE 322 -#define ADD 323 -#define SUB 324 -#define MUL 325 -#define DIV 326 -#define REM 327 -#define AND 328 -#define OR 329 -#define XOR 330 -#define SETLE 331 -#define SETGE 332 -#define SETLT 333 -#define SETGT 334 -#define SETEQ 335 -#define SETNE 336 -#define VSETLE 337 -#define VSETGE 338 -#define VSETLT 339 -#define VSETGT 340 -#define VSETEQ 341 -#define VSETNE 342 -#define MALLOC 343 -#define ALLOCA 344 -#define FREE 345 -#define LOAD 346 -#define STORE 347 -#define GETELEMENTPTR 348 -#define PHI_TOK 349 -#define CAST 350 -#define SELECT 351 -#define VSELECT 352 -#define SHL 353 -#define SHR 354 -#define VAARG 355 -#define VGATHER 356 -#define VIMM 357 -#define VSCATTER 358 -#define EXTRACT 359 -#define EXTRACTELEMENT 360 -#define COMBINE 361 -#define COMBINEELEMENT 362 -#define VAARG_old 363 -#define VANEXT_old 364 -#line 14 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + ESINT64VAL = 258, + EUINT64VAL = 259, + SINTVAL = 260, + UINTVAL = 261, + FPVAL = 262, + VOID = 263, + BOOL = 264, + SBYTE = 265, + UBYTE = 266, + SHORT = 267, + USHORT = 268, + INT = 269, + UINT = 270, + LONG = 271, + ULONG = 272, + FLOAT = 273, + DOUBLE = 274, + TYPE = 275, + LABEL = 276, + VAR_ID = 277, + LABELSTR = 278, + STRINGCONSTANT = 279, + IMPLEMENTATION = 280, + ZEROINITIALIZER = 281, + TRUETOK = 282, + FALSETOK = 283, + BEGINTOK = 284, + ENDTOK = 285, + DECLARE = 286, + GLOBAL = 287, + CONSTANT = 288, + SECTION = 289, + VOLATILE = 290, + FIXED = 291, + TO = 292, + DOTDOTDOT = 293, + NULL_TOK = 294, + UNDEF = 295, + CONST = 296, + INTERNAL = 297, + LINKONCE = 298, + WEAK = 299, + APPENDING = 300, + OPAQUE = 301, + NOT = 302, + EXTERNAL = 303, + TARGET = 304, + TRIPLE = 305, + ENDIAN = 306, + POINTERSIZE = 307, + LITTLE = 308, + BIG = 309, + ALIGN = 310, + DEPLIBS = 311, + CALL = 312, + TAIL = 313, + CC_TOK = 314, + CCC_TOK = 315, + FASTCC_TOK = 316, + COLDCC_TOK = 317, + VECTOR = 318, + OF = 319, + RET = 320, + BR = 321, + SWITCH = 322, + INVOKE = 323, + UNWIND = 324, + UNREACHABLE = 325, + ADD = 326, + SUB = 327, + MUL = 328, + DIV = 329, + REM = 330, + AND = 331, + OR = 332, + XOR = 333, + SETLE = 334, + SETGE = 335, + SETLT = 336, + SETGT = 337, + SETEQ = 338, + SETNE = 339, + VSETLE = 340, + VSETGE = 341, + VSETLT = 342, + VSETGT = 343, + VSETEQ = 344, + VSETNE = 345, + MALLOC = 346, + ALLOCA = 347, + FREE = 348, + LOAD = 349, + STORE = 350, + GETELEMENTPTR = 351, + PHI_TOK = 352, + CAST = 353, + SELECT = 354, + VSELECT = 355, + SHL = 356, + SHR = 357, + VAARG = 358, + VGATHER = 359, + VIMM = 360, + VSCATTER = 361, + EXTRACT = 362, + EXTRACTELEMENT = 363, + COMBINE = 364, + COMBINEELEMENT = 365, + VAARG_old = 366, + VANEXT_old = 367 + }; +#endif +#define ESINT64VAL 258 +#define EUINT64VAL 259 +#define SINTVAL 260 +#define UINTVAL 261 +#define FPVAL 262 +#define VOID 263 +#define BOOL 264 +#define SBYTE 265 +#define UBYTE 266 +#define SHORT 267 +#define USHORT 268 +#define INT 269 +#define UINT 270 +#define LONG 271 +#define ULONG 272 +#define FLOAT 273 +#define DOUBLE 274 +#define TYPE 275 +#define LABEL 276 +#define VAR_ID 277 +#define LABELSTR 278 +#define STRINGCONSTANT 279 +#define IMPLEMENTATION 280 +#define ZEROINITIALIZER 281 +#define TRUETOK 282 +#define FALSETOK 283 +#define BEGINTOK 284 +#define ENDTOK 285 +#define DECLARE 286 +#define GLOBAL 287 +#define CONSTANT 288 +#define SECTION 289 +#define VOLATILE 290 +#define FIXED 291 +#define TO 292 +#define DOTDOTDOT 293 +#define NULL_TOK 294 +#define UNDEF 295 +#define CONST 296 +#define INTERNAL 297 +#define LINKONCE 298 +#define WEAK 299 +#define APPENDING 300 +#define OPAQUE 301 +#define NOT 302 +#define EXTERNAL 303 +#define TARGET 304 +#define TRIPLE 305 +#define ENDIAN 306 +#define POINTERSIZE 307 +#define LITTLE 308 +#define BIG 309 +#define ALIGN 310 +#define DEPLIBS 311 +#define CALL 312 +#define TAIL 313 +#define CC_TOK 314 +#define CCC_TOK 315 +#define FASTCC_TOK 316 +#define COLDCC_TOK 317 +#define VECTOR 318 +#define OF 319 +#define RET 320 +#define BR 321 +#define SWITCH 322 +#define INVOKE 323 +#define UNWIND 324 +#define UNREACHABLE 325 +#define ADD 326 +#define SUB 327 +#define MUL 328 +#define DIV 329 +#define REM 330 +#define AND 331 +#define OR 332 +#define XOR 333 +#define SETLE 334 +#define SETGE 335 +#define SETLT 336 +#define SETGT 337 +#define SETEQ 338 +#define SETNE 339 +#define VSETLE 340 +#define VSETGE 341 +#define VSETLT 342 +#define VSETGT 343 +#define VSETEQ 344 +#define VSETNE 345 +#define MALLOC 346 +#define ALLOCA 347 +#define FREE 348 +#define LOAD 349 +#define STORE 350 +#define GETELEMENTPTR 351 +#define PHI_TOK 352 +#define CAST 353 +#define SELECT 354 +#define VSELECT 355 +#define SHL 356 +#define SHR 357 +#define VAARG 358 +#define VGATHER 359 +#define VIMM 360 +#define VSCATTER 361 +#define EXTRACT 362 +#define EXTRACTELEMENT 363 +#define COMBINE 364 +#define COMBINEELEMENT 365 +#define VAARG_old 366 +#define VANEXT_old 367 + + + + +/* Copy the first part of user declarations. */ +#line 14 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" #include "ParserInternals.h" #include "llvm/CallingConv.h" @@ -129,6 +298,7 @@ #include "llvm/SymbolTable.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/MathExtras.h" #include #include #include @@ -159,7 +329,8 @@ static bool ObsoleteVarArgs; static bool NewVarArgs; -static BasicBlock* CurBB; +static BasicBlock *CurBB; +static GlobalVariable *CurGV; // This contains info used when building the body of a function. It is @@ -624,9 +795,10 @@ /// ParseGlobalVariable - Handle parsing of a global. If Initializer is null, /// this is a declaration, otherwise it is a definition. -static void ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage, - bool isConstantGlobal, const Type *Ty, - Constant *Initializer) { +static GlobalVariable * +ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage, + bool isConstantGlobal, const Type *Ty, + Constant *Initializer) { if (isa(Ty)) ThrowException("Cannot declare global vars of function type!"); @@ -657,7 +829,7 @@ GV->setLinkage(Linkage); GV->setConstant(isConstantGlobal); InsertValue(GV, CurModule.Values); - return; + return GV; } // If this global has a name, check to see if there is already a definition @@ -682,7 +854,7 @@ if (isConstantGlobal) EGV->setConstant(true); EGV->setLinkage(Linkage); - return; + return EGV; } ThrowException("Redefinition of global variable named '" + Name + @@ -695,6 +867,7 @@ new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name, CurModule.CurrentModule); InsertValue(GV, CurModule.Values); + return GV; } // setTypeName - Set the specified type to the name given. The name may be @@ -876,7 +1049,7 @@ const Type* ArgTy = F->getFunctionType()->getReturnType(); const Type* ArgTyPtr = PointerType::get(ArgTy); Function* NF = Result->getOrInsertFunction("llvm.va_start", - RetTy, ArgTyPtr, 0); + RetTy, ArgTyPtr, (Type *)0); while (!F->use_empty()) { CallInst* CI = cast(F->use_back()); @@ -901,7 +1074,7 @@ const Type* ArgTy = F->getFunctionType()->getParamType(0); const Type* ArgTyPtr = PointerType::get(ArgTy); Function* NF = Result->getOrInsertFunction("llvm.va_end", - RetTy, ArgTyPtr, 0); + RetTy, ArgTyPtr, (Type *)0); while (!F->use_empty()) { CallInst* CI = cast(F->use_back()); @@ -928,7 +1101,8 @@ const Type* ArgTy = F->getFunctionType()->getReturnType(); const Type* ArgTyPtr = PointerType::get(ArgTy); Function* NF = Result->getOrInsertFunction("llvm.va_copy", - RetTy, ArgTyPtr, ArgTyPtr, 0); + RetTy, ArgTyPtr, ArgTyPtr, + (Type *)0); while (!F->use_empty()) { CallInst* CI = cast(F->use_back()); @@ -971,8 +1145,23 @@ } -#line 865 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -typedef union { + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 870 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" +typedef union YYSTYPE { llvm::Module *ModuleVal; llvm::Function *FunctionVal; std::pair *ArgVal; @@ -1011,981 +1200,1347 @@ llvm::Instruction::OtherOps OtherOpVal; llvm::Module::Endianness Endianness; } YYSTYPE; -#include - -#ifndef __cplusplus -#ifndef __STDC__ -#define const -#endif +/* Line 191 of yacc.c. */ +#line 1204 "llvmAsmParser.tab.c" +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 #endif -#define YYFINAL 480 -#define YYFLAG -32768 -#define YYNTBASE 125 - -#define YYTRANSLATE(x) ((unsigned)(x) <= 364 ? yytranslate[x] : 188) - -static const char yytranslate[] = { 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 113, - 114, 120, 2, 121, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 123, - 111, 124, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 115, 112, 117, 2, 2, 2, 2, 2, 122, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 116, - 2, 2, 118, 2, 119, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110 -}; +/* Copy the second part of user declarations. */ + + +/* Line 214 of yacc.c. */ +#line 1216 "llvmAsmParser.tab.c" + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# else +# ifndef YYSTACK_USE_ALLOCA +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC malloc +# define YYSTACK_FREE free +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (YYSTYPE_IS_TRIVIAL))) -#if YYDEBUG != 0 -static const short yyprhs[] = { 0, - 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, - 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, - 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, - 60, 62, 64, 66, 68, 70, 72, 74, 76, 79, - 80, 82, 84, 86, 88, 89, 90, 92, 94, 96, - 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, - 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, - 139, 141, 144, 149, 155, 161, 168, 172, 175, 178, - 180, 184, 186, 190, 192, 193, 198, 202, 206, 211, - 216, 220, 223, 226, 229, 232, 235, 238, 241, 244, - 247, 250, 257, 263, 272, 279, 286, 293, 300, 304, - 306, 308, 310, 312, 315, 318, 321, 323, 328, 331, - 337, 343, 347, 352, 353, 355, 357, 361, 365, 369, - 373, 377, 379, 380, 382, 384, 386, 387, 390, 394, - 396, 398, 402, 404, 405, 412, 414, 416, 420, 422, - 424, 427, 428, 432, 434, 436, 438, 440, 442, 444, - 446, 450, 452, 454, 456, 458, 460, 463, 466, 469, - 473, 476, 477, 479, 482, 485, 489, 499, 509, 518, - 532, 534, 536, 543, 549, 552, 559, 567, 569, 573, - 575, 576, 579, 581, 587, 593, 599, 605, 608, 613, - 618, 625, 632, 637, 642, 647, 650, 658, 660, 663, - 664, 666, 667, 669, 670, 673, 679, 682, 688, 691, - 696, 703, 708, 713, 719, 728, 733, 742, 749 -}; +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short yyss; + YYSTYPE yyvs; + }; -static const short yyrhs[] = { 5, - 0, 6, 0, 3, 0, 4, 0, 69, 0, 70, - 0, 71, 0, 72, 0, 73, 0, 74, 0, 75, - 0, 76, 0, 77, 0, 78, 0, 79, 0, 80, - 0, 81, 0, 82, 0, 83, 0, 84, 0, 85, - 0, 86, 0, 87, 0, 88, 0, 99, 0, 100, - 0, 16, 0, 14, 0, 12, 0, 10, 0, 17, - 0, 15, 0, 13, 0, 11, 0, 132, 0, 133, - 0, 18, 0, 19, 0, 157, 111, 0, 0, 41, - 0, 42, 0, 43, 0, 44, 0, 0, 0, 58, - 0, 59, 0, 60, 0, 57, 4, 0, 141, 0, - 8, 0, 143, 0, 8, 0, 143, 0, 9, 0, - 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, - 15, 0, 16, 0, 17, 0, 18, 0, 19, 0, - 20, 0, 21, 0, 45, 0, 142, 0, 170, 0, - 112, 4, 0, 140, 113, 145, 114, 0, 115, 4, - 116, 143, 117, 0, 115, 61, 62, 143, 117, 0, - 115, 61, 62, 4, 143, 117, 0, 118, 144, 119, - 0, 118, 119, 0, 143, 120, 0, 143, 0, 144, - 121, 143, 0, 144, 0, 144, 121, 37, 0, 37, - 0, 0, 141, 115, 148, 117, 0, 141, 115, 117, - 0, 141, 122, 24, 0, 141, 123, 148, 124, 0, - 141, 118, 148, 119, 0, 141, 118, 119, 0, 141, - 38, 0, 141, 39, 0, 141, 170, 0, 141, 147, - 0, 141, 26, 0, 132, 126, 0, 133, 4, 0, - 9, 27, 0, 9, 28, 0, 135, 7, 0, 96, - 113, 146, 36, 141, 114, 0, 94, 113, 146, 184, - 114, 0, 97, 113, 146, 121, 146, 121, 146, 114, - 0, 127, 113, 146, 121, 146, 114, 0, 128, 113, - 146, 121, 146, 114, 0, 129, 113, 146, 121, 146, - 114, 0, 131, 113, 146, 121, 146, 114, 0, 148, - 121, 146, 0, 146, 0, 32, 0, 33, 0, 151, - 0, 151, 166, 0, 151, 167, 0, 151, 25, 0, - 152, 0, 152, 136, 20, 139, 0, 152, 167, 0, - 152, 136, 137, 149, 146, 0, 152, 136, 47, 149, - 141, 0, 152, 48, 154, 0, 152, 54, 111, 155, - 0, 0, 53, 0, 52, 0, 50, 111, 153, 0, - 51, 111, 4, 0, 49, 111, 24, 0, 115, 156, - 117, 0, 156, 121, 24, 0, 24, 0, 0, 22, - 0, 24, 0, 157, 0, 0, 141, 158, 0, 160, - 121, 159, 0, 159, 0, 160, 0, 160, 121, 37, - 0, 37, 0, 0, 138, 139, 157, 113, 161, 114, - 0, 29, 0, 118, 0, 137, 162, 163, 0, 30, - 0, 119, 0, 173, 165, 0, 0, 31, 168, 162, - 0, 3, 0, 4, 0, 7, 0, 27, 0, 28, - 0, 38, 0, 39, 0, 123, 148, 124, 0, 147, - 0, 125, 0, 157, 0, 170, 0, 169, 0, 141, - 171, 0, 173, 174, 0, 164, 174, 0, 175, 136, - 176, 0, 175, 178, 0, 0, 23, 0, 63, 172, - 0, 63, 8, 0, 64, 21, 171, 0, 64, 9, - 171, 121, 21, 171, 121, 21, 171, 0, 65, 134, - 171, 121, 21, 171, 115, 177, 117, 0, 65, 134, - 171, 121, 21, 171, 115, 117, 0, 66, 138, 139, - 171, 113, 181, 114, 36, 21, 171, 67, 21, 171, - 0, 67, 0, 68, 0, 177, 134, 169, 121, 21, - 171, 0, 134, 169, 121, 21, 171, 0, 136, 183, - 0, 141, 115, 171, 121, 171, 117, 0, 179, 121, - 115, 171, 121, 171, 117, 0, 172, 0, 180, 121, - 172, 0, 180, 0, 0, 56, 55, 0, 55, 0, - 127, 141, 171, 121, 171, 0, 128, 141, 171, 121, - 171, 0, 129, 141, 171, 121, 171, 0, 130, 141, - 171, 121, 171, 0, 46, 172, 0, 131, 172, 121, - 172, 0, 96, 172, 36, 141, 0, 97, 172, 121, - 172, 121, 172, 0, 98, 172, 121, 172, 121, 172, - 0, 101, 172, 121, 141, 0, 109, 172, 121, 141, - 0, 110, 172, 121, 141, 0, 95, 179, 0, 182, - 138, 139, 171, 113, 181, 114, 0, 187, 0, 121, - 180, 0, 0, 34, 0, 0, 35, 0, 0, 89, - 141, 0, 89, 141, 121, 15, 171, 0, 90, 141, - 0, 90, 141, 121, 15, 171, 0, 91, 172, 0, - 185, 92, 141, 171, 0, 185, 93, 172, 121, 141, - 171, 0, 94, 141, 171, 184, 0, 102, 141, 171, - 184, 0, 186, 103, 172, 121, 172, 0, 105, 172, - 121, 172, 121, 172, 121, 172, 0, 106, 172, 121, - 172, 0, 107, 172, 121, 172, 121, 172, 121, 172, - 0, 108, 172, 121, 172, 121, 172, 0, 104, 172, - 121, 141, 171, 184, 0 -}; +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) -#endif +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) -#if YYDEBUG != 0 -static const short yyrline[] = { 0, - 986, 987, 994, 995, 1004, 1004, 1004, 1004, 1004, 1005, - 1005, 1005, 1006, 1006, 1006, 1006, 1006, 1006, 1007, 1007, - 1007, 1007, 1007, 1007, 1009, 1009, 1013, 1013, 1013, 1013, - 1014, 1014, 1014, 1014, 1015, 1015, 1016, 1016, 1019, 1022, - 1026, 1026, 1027, 1028, 1029, 1032, 1032, 1033, 1034, 1035, - 1049, 1049, 1050, 1050, 1052, 1061, 1061, 1061, 1061, 1061, - 1061, 1061, 1062, 1062, 1062, 1062, 1062, 1062, 1063, 1066, - 1069, 1075, 1082, 1094, 1099, 1104, 1116, 1125, 1128, 1136, - 1140, 1145, 1146, 1149, 1152, 1162, 1187, 1200, 1228, 1253, - 1273, 1285, 1294, 1298, 1357, 1363, 1371, 1376, 1381, 1384, - 1387, 1394, 1404, 1435, 1442, 1463, 1471, 1476, 1488, 1491, - 1498, 1498, 1508, 1515, 1519, 1522, 1525, 1538, 1558, 1560, - 1564, 1568, 1570, 1572, 1577, 1578, 1580, 1583, 1591, 1596, - 1598, 1602, 1606, 1614, 1614, 1615, 1615, 1617, 1623, 1628, - 1634, 1637, 1642, 1646, 1650, 1730, 1730, 1732, 1740, 1740, - 1742, 1746, 1746, 1755, 1758, 1761, 1764, 1767, 1770, 1773, - 1776, 1800, 1807, 1810, 1815, 1815, 1821, 1825, 1828, 1836, - 1845, 1849, 1859, 1870, 1873, 1876, 1879, 1882, 1896, 1900, - 1953, 1956, 1962, 1970, 1980, 1987, 1992, 1998, 2002, 2008, - 2008, 2010, 2013, 2019, 2032, 2041, 2047, 2053, 2065, 2073, - 2080, 2087, 2096, 2101, 2120, 2142, 2156, 2213, 2219, 2221, - 2225, 2228, 2232, 2235, 2240, 2244, 2248, 2252, 2256, 2263, - 2274, 2288, 2310, 2325, 2331, 2343, 2351, 2363, 2373 -}; #endif - -#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) - -static const char * const yytname[] = { "$","error","$undefined.","ESINT64VAL", -"EUINT64VAL","SINTVAL","UINTVAL","FPVAL","VOID","BOOL","SBYTE","UBYTE","SHORT", -"USHORT","INT","UINT","LONG","ULONG","FLOAT","DOUBLE","TYPE","LABEL","VAR_ID", -"LABELSTR","STRINGCONSTANT","IMPLEMENTATION","ZEROINITIALIZER","TRUETOK","FALSETOK", -"BEGINTOK","ENDTOK","DECLARE","GLOBAL","CONSTANT","VOLATILE","FIXED","TO","DOTDOTDOT", -"NULL_TOK","UNDEF","CONST","INTERNAL","LINKONCE","WEAK","APPENDING","OPAQUE", -"NOT","EXTERNAL","TARGET","TRIPLE","ENDIAN","POINTERSIZE","LITTLE","BIG","DEPLIBS", -"CALL","TAIL","CC_TOK","CCC_TOK","FASTCC_TOK","COLDCC_TOK","VECTOR","OF","RET", -"BR","SWITCH","INVOKE","UNWIND","UNREACHABLE","ADD","SUB","MUL","DIV","REM", -"AND","OR","XOR","SETLE","SETGE","SETLT","SETGT","SETEQ","SETNE","VSETLE","VSETGE", -"VSETLT","VSETGT","VSETEQ","VSETNE","MALLOC","ALLOCA","FREE","LOAD","STORE", -"GETELEMENTPTR","PHI_TOK","CAST","SELECT","VSELECT","SHL","SHR","VAARG","VGATHER", -"VIMM","VSCATTER","EXTRACT","EXTRACTELEMENT","COMBINE","COMBINEELEMENT","VAARG_old", -"VANEXT_old","'='","'\\\\'","'('","')'","'['","'x'","']'","'{'","'}'","'*'", -"','","'c'","'<'","'>'","INTVAL","EINT64VAL","ArithmeticOps","LogicalOps","SetCondOps", -"VSetCondOps","ShiftOps","SIntType","UIntType","IntType","FPType","OptAssign", -"OptLinkage","OptCallingConv","TypesV","UpRTypesV","Types","PrimType","UpRTypes", -"TypeListI","ArgTypeListI","ConstVal","ConstExpr","ConstVector","GlobalType", -"Module","FunctionList","ConstPool","BigOrLittle","TargetDefinition","LibrariesDefinition", -"LibList","Name","OptName","ArgVal","ArgListH","ArgList","FunctionHeaderH","BEGIN", -"FunctionHeader","END","Function","FunctionProto","@1","ConstValueRef","SymbolicValueRef", -"ValueRef","ResolvedVal","BasicBlockList","BasicBlock","InstructionList","BBTerminatorInst", -"JumpTable","Inst","PHIList","ValueRefList","ValueRefListE","OptTailCall","InstVal", -"IndexList","OptVolatile","OptFixed","MemoryInst", NULL -}; +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short yysigned_char; #endif -static const short yyr1[] = { 0, - 125, 125, 126, 126, 127, 127, 127, 127, 127, 128, - 128, 128, 129, 129, 129, 129, 129, 129, 130, 130, - 130, 130, 130, 130, 131, 131, 132, 132, 132, 132, - 133, 133, 133, 133, 134, 134, 135, 135, 136, 136, - 137, 137, 137, 137, 137, 138, 138, 138, 138, 138, - 139, 139, 140, 140, 141, 142, 142, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 142, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 144, - 144, 145, 145, 145, 145, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 147, 147, 147, 147, 147, 147, 147, 148, 148, - 149, 149, 150, 151, 151, 151, 151, 152, 152, 152, - 152, 152, 152, 152, 153, 153, 154, 154, 154, 155, - 156, 156, 156, 157, 157, 158, 158, 159, 160, 160, - 161, 161, 161, 161, 162, 163, 163, 164, 165, 165, - 166, 168, 167, 169, 169, 169, 169, 169, 169, 169, - 169, 169, 170, 170, 171, 171, 172, 173, 173, 174, - 175, 175, 175, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 177, 177, 178, 179, 179, 180, 180, 181, - 181, 182, 182, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 184, 184, - 185, 185, 186, 186, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187 +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 4 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 1382 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 127 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 72 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 243 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 504 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 367 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 116, 117, 123, 2, 114, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 125, 113, 126, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 118, 115, 120, 2, 2, 2, 2, 2, 124, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 119, 2, 2, 121, 2, 122, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112 }; -static const short yyr2[] = { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, - 1, 1, 1, 1, 0, 0, 1, 1, 1, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 4, 5, 5, 6, 3, 2, 2, 1, - 3, 1, 3, 1, 0, 4, 3, 3, 4, 4, - 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 6, 5, 8, 6, 6, 6, 6, 3, 1, - 1, 1, 1, 2, 2, 2, 1, 4, 2, 5, - 5, 3, 4, 0, 1, 1, 3, 3, 3, 3, - 3, 1, 0, 1, 1, 1, 0, 2, 3, 1, - 1, 3, 1, 0, 6, 1, 1, 3, 1, 1, - 2, 0, 3, 1, 1, 1, 1, 1, 1, 1, - 3, 1, 1, 1, 1, 1, 2, 2, 2, 3, - 2, 0, 1, 2, 2, 3, 9, 9, 8, 13, - 1, 1, 6, 5, 2, 6, 7, 1, 3, 1, - 0, 2, 1, 5, 5, 5, 5, 2, 4, 4, - 6, 6, 4, 4, 4, 2, 7, 1, 2, 0, - 1, 0, 1, 0, 2, 5, 2, 5, 2, 4, - 6, 4, 4, 5, 8, 4, 8, 6, 6 +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned short yyprhs[] = +{ + 0, 0, 3, 5, 7, 9, 11, 13, 15, 17, + 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, + 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, + 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, + 79, 82, 83, 85, 87, 89, 91, 92, 93, 95, + 97, 99, 102, 103, 106, 107, 111, 114, 115, 117, + 118, 122, 124, 127, 129, 131, 133, 135, 137, 139, + 141, 143, 145, 147, 149, 151, 153, 155, 157, 159, + 161, 163, 165, 167, 169, 172, 177, 183, 189, 196, + 200, 203, 206, 208, 212, 214, 218, 220, 221, 226, + 230, 234, 239, 244, 248, 251, 254, 257, 260, 263, + 266, 269, 272, 275, 278, 285, 291, 300, 307, 314, + 321, 328, 332, 334, 336, 338, 340, 343, 346, 349, + 351, 356, 359, 360, 368, 369, 377, 381, 386, 387, + 389, 391, 395, 399, 403, 407, 411, 413, 414, 416, + 418, 420, 421, 424, 428, 430, 432, 436, 438, 439, + 448, 450, 452, 456, 458, 460, 463, 464, 468, 470, + 472, 474, 476, 478, 480, 482, 486, 488, 490, 492, + 494, 496, 499, 502, 505, 509, 512, 513, 515, 518, + 521, 525, 535, 545, 554, 568, 570, 572, 579, 585, + 588, 595, 603, 605, 609, 611, 612, 615, 617, 623, + 629, 635, 641, 644, 649, 654, 661, 668, 673, 678, + 683, 686, 694, 696, 699, 700, 702, 703, 705, 706, + 710, 717, 721, 728, 731, 736, 743, 748, 753, 759, + 768, 773, 782, 789 }; -static const short yydefact[] = { 124, - 45, 117, 116, 152, 41, 42, 43, 44, 46, 172, - 114, 115, 172, 134, 135, 0, 0, 45, 0, 119, - 46, 0, 47, 48, 49, 0, 0, 173, 169, 40, - 149, 150, 151, 168, 0, 0, 0, 122, 0, 0, - 0, 0, 39, 153, 50, 1, 2, 52, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 0, 0, 0, 163, 0, 0, 51, 70, - 55, 164, 71, 146, 147, 148, 212, 171, 0, 0, - 0, 133, 123, 118, 111, 112, 0, 0, 72, 0, - 0, 54, 78, 80, 0, 0, 85, 79, 211, 213, - 0, 193, 0, 0, 0, 0, 46, 181, 182, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, - 0, 0, 0, 0, 0, 0, 0, 25, 26, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 170, 46, 185, 0, 0, 208, 129, - 126, 125, 127, 128, 132, 0, 121, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 0, 0, - 0, 0, 120, 0, 0, 77, 0, 144, 84, 82, - 0, 0, 198, 192, 175, 174, 0, 0, 30, 34, - 29, 33, 28, 32, 27, 31, 35, 36, 0, 0, - 215, 217, 219, 0, 0, 206, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 130, 0, 99, - 100, 3, 4, 97, 98, 101, 96, 92, 93, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 95, 94, 53, 0, 53, 81, 143, 137, 140, 141, - 0, 0, 73, 154, 155, 156, 157, 158, 159, 160, - 0, 162, 166, 165, 167, 0, 176, 0, 0, 0, - 0, 210, 0, 0, 0, 0, 0, 0, 210, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 131, 0, 0, 0, 87, - 110, 0, 91, 0, 88, 0, 0, 0, 0, 0, - 74, 53, 75, 136, 138, 0, 145, 83, 0, 0, - 0, 0, 0, 0, 0, 222, 0, 0, 200, 0, - 0, 203, 223, 0, 0, 226, 0, 0, 204, 205, - 0, 0, 0, 0, 199, 0, 220, 0, 0, 210, - 0, 0, 86, 0, 90, 89, 0, 0, 0, 0, - 76, 142, 139, 161, 0, 0, 191, 216, 218, 188, - 209, 0, 0, 0, 0, 210, 0, 0, 0, 194, - 195, 196, 197, 191, 0, 224, 0, 0, 0, 109, - 0, 0, 0, 0, 0, 0, 190, 0, 0, 0, - 0, 201, 202, 229, 0, 0, 228, 0, 221, 103, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, - 186, 0, 0, 0, 207, 102, 0, 105, 106, 107, - 108, 0, 179, 0, 0, 0, 187, 225, 227, 0, - 177, 0, 178, 0, 0, 104, 0, 0, 0, 0, - 0, 0, 184, 0, 0, 183, 180, 0, 0, 0 +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const short yyrhs[] = +{ + 159, 0, -1, 5, -1, 6, -1, 3, -1, 4, + -1, 71, -1, 72, -1, 73, -1, 74, -1, 75, + -1, 76, -1, 77, -1, 78, -1, 79, -1, 80, + -1, 81, -1, 82, -1, 83, -1, 84, -1, 85, + -1, 86, -1, 87, -1, 88, -1, 89, -1, 90, + -1, 101, -1, 102, -1, 16, -1, 14, -1, 12, + -1, 10, -1, 17, -1, 15, -1, 13, -1, 11, + -1, 135, -1, 136, -1, 18, -1, 19, -1, 168, + 113, -1, -1, 42, -1, 43, -1, 44, -1, 45, + -1, -1, -1, 60, -1, 61, -1, 62, -1, 59, + 4, -1, -1, 55, 4, -1, -1, 114, 55, 4, + -1, 34, 24, -1, -1, 144, -1, -1, 114, 147, + 146, -1, 144, -1, 55, 4, -1, 150, -1, 8, + -1, 152, -1, 8, -1, 152, -1, 9, -1, 10, + -1, 11, -1, 12, -1, 13, -1, 14, -1, 15, + -1, 16, -1, 17, -1, 18, -1, 19, -1, 20, + -1, 21, -1, 46, -1, 151, -1, 181, -1, 115, + 4, -1, 149, 116, 154, 117, -1, 118, 4, 119, + 152, 120, -1, 118, 63, 64, 152, 120, -1, 118, + 63, 64, 4, 152, 120, -1, 121, 153, 122, -1, + 121, 122, -1, 152, 123, -1, 152, -1, 153, 114, + 152, -1, 153, -1, 153, 114, 38, -1, 38, -1, + -1, 150, 118, 157, 120, -1, 150, 118, 120, -1, + 150, 124, 24, -1, 150, 125, 157, 126, -1, 150, + 121, 157, 122, -1, 150, 121, 122, -1, 150, 39, + -1, 150, 40, -1, 150, 181, -1, 150, 156, -1, + 150, 26, -1, 135, 129, -1, 136, 4, -1, 9, + 27, -1, 9, 28, -1, 138, 7, -1, 98, 116, + 155, 37, 150, 117, -1, 96, 116, 155, 195, 117, + -1, 99, 116, 155, 114, 155, 114, 155, 117, -1, + 130, 116, 155, 114, 155, 117, -1, 131, 116, 155, + 114, 155, 117, -1, 132, 116, 155, 114, 155, 117, + -1, 134, 116, 155, 114, 155, 117, -1, 157, 114, + 155, -1, 155, -1, 32, -1, 33, -1, 160, -1, + 160, 177, -1, 160, 178, -1, 160, 25, -1, 161, + -1, 161, 139, 20, 148, -1, 161, 178, -1, -1, + 161, 139, 140, 158, 155, 162, 146, -1, -1, 161, + 139, 48, 158, 150, 163, 146, -1, 161, 49, 165, + -1, 161, 56, 113, 166, -1, -1, 54, -1, 53, + -1, 51, 113, 164, -1, 52, 113, 4, -1, 50, + 113, 24, -1, 118, 167, 120, -1, 167, 114, 24, + -1, 24, -1, -1, 22, -1, 24, -1, 168, -1, + -1, 150, 169, -1, 171, 114, 170, -1, 170, -1, + 171, -1, 171, 114, 38, -1, 38, -1, -1, 141, + 148, 168, 116, 172, 117, 145, 142, -1, 29, -1, + 121, -1, 140, 173, 174, -1, 30, -1, 122, -1, + 184, 176, -1, -1, 31, 179, 173, -1, 3, -1, + 4, -1, 7, -1, 27, -1, 28, -1, 39, -1, + 40, -1, 125, 157, 126, -1, 156, -1, 128, -1, + 168, -1, 181, -1, 180, -1, 150, 182, -1, 184, + 185, -1, 175, 185, -1, 186, 139, 187, -1, 186, + 189, -1, -1, 23, -1, 65, 183, -1, 65, 8, + -1, 66, 21, 182, -1, 66, 9, 182, 114, 21, + 182, 114, 21, 182, -1, 67, 137, 182, 114, 21, + 182, 118, 188, 120, -1, 67, 137, 182, 114, 21, + 182, 118, 120, -1, 68, 141, 148, 182, 116, 192, + 117, 37, 21, 182, 69, 21, 182, -1, 69, -1, + 70, -1, 188, 137, 180, 114, 21, 182, -1, 137, + 180, 114, 21, 182, -1, 139, 194, -1, 150, 118, + 182, 114, 182, 120, -1, 190, 114, 118, 182, 114, + 182, 120, -1, 183, -1, 191, 114, 183, -1, 191, + -1, -1, 58, 57, -1, 57, -1, 130, 150, 182, + 114, 182, -1, 131, 150, 182, 114, 182, -1, 132, + 150, 182, 114, 182, -1, 133, 150, 182, 114, 182, + -1, 47, 183, -1, 134, 183, 114, 183, -1, 98, + 183, 37, 150, -1, 99, 183, 114, 183, 114, 183, + -1, 100, 183, 114, 183, 114, 183, -1, 103, 183, + 114, 150, -1, 111, 183, 114, 150, -1, 112, 183, + 114, 150, -1, 97, 190, -1, 193, 141, 148, 182, + 116, 192, 117, -1, 198, -1, 114, 191, -1, -1, + 35, -1, -1, 36, -1, -1, 91, 150, 143, -1, + 91, 150, 114, 15, 182, 143, -1, 92, 150, 143, + -1, 92, 150, 114, 15, 182, 143, -1, 93, 183, + -1, 196, 94, 150, 182, -1, 196, 95, 183, 114, + 150, 182, -1, 96, 150, 182, 195, -1, 104, 150, + 182, 195, -1, 197, 105, 183, 114, 183, -1, 107, + 183, 114, 183, 114, 183, 114, 183, -1, 108, 183, + 114, 183, -1, 109, 183, 114, 183, 114, 183, 114, + 183, -1, 110, 183, 114, 183, 114, 183, -1, 106, + 183, 114, 150, 182, 195, -1 }; -static const short yydefgoto[] = { 66, - 244, 257, 258, 259, 152, 260, 179, 180, 209, 181, - 18, 9, 26, 67, 68, 192, 70, 71, 95, 191, - 321, 282, 322, 87, 478, 1, 2, 163, 38, 83, - 166, 72, 335, 269, 270, 271, 27, 76, 10, 33, - 11, 12, 21, 283, 73, 285, 390, 13, 29, 30, - 154, 455, 78, 216, 417, 418, 155, 156, 346, 157, - 158, 159 +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short yyrline[] = +{ + 0, 992, 992, 993, 1000, 1001, 1010, 1010, 1010, 1010, + 1010, 1011, 1011, 1011, 1012, 1012, 1012, 1012, 1012, 1012, + 1013, 1013, 1013, 1013, 1013, 1013, 1015, 1015, 1019, 1019, + 1019, 1019, 1020, 1020, 1020, 1020, 1021, 1021, 1022, 1022, + 1025, 1028, 1032, 1033, 1034, 1035, 1036, 1038, 1039, 1040, + 1041, 1042, 1050, 1051, 1056, 1057, 1064, 1071, 1072, 1077, + 1078, 1079, 1083, 1096, 1096, 1097, 1097, 1099, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1109, 1109, 1109, 1109, 1109, + 1109, 1110, 1113, 1116, 1122, 1129, 1141, 1145, 1150, 1164, + 1173, 1176, 1184, 1188, 1193, 1194, 1197, 1200, 1210, 1235, + 1248, 1276, 1301, 1321, 1333, 1342, 1346, 1405, 1411, 1419, + 1424, 1429, 1432, 1435, 1442, 1452, 1483, 1490, 1511, 1519, + 1524, 1536, 1539, 1546, 1546, 1556, 1563, 1567, 1570, 1573, + 1586, 1606, 1608, 1608, 1614, 1614, 1621, 1623, 1625, 1630, + 1631, 1633, 1636, 1644, 1649, 1651, 1655, 1659, 1667, 1667, + 1668, 1668, 1670, 1676, 1681, 1687, 1690, 1695, 1699, 1703, + 1789, 1789, 1791, 1799, 1799, 1801, 1805, 1805, 1814, 1817, + 1820, 1823, 1826, 1829, 1832, 1835, 1859, 1866, 1869, 1874, + 1874, 1880, 1884, 1887, 1895, 1904, 1908, 1918, 1929, 1932, + 1935, 1938, 1941, 1955, 1959, 2012, 2015, 2021, 2029, 2039, + 2046, 2051, 2057, 2061, 2067, 2067, 2069, 2072, 2078, 2091, + 2100, 2106, 2112, 2124, 2132, 2139, 2146, 2155, 2160, 2179, + 2201, 2215, 2272, 2278, 2280, 2284, 2287, 2291, 2294, 2299, + 2303, 2307, 2311, 2315, 2322, 2333, 2347, 2369, 2384, 2390, + 2402, 2410, 2422, 2432 }; +#endif -static const short yypact[] = {-32768, - 11, 169,-32768,-32768,-32768,-32768,-32768,-32768, 40, -11, --32768,-32768, -17,-32768,-32768, 68, -68, 93, -61,-32768, - 40, 66,-32768,-32768,-32768, 1089, -22,-32768,-32768, 34, --32768,-32768,-32768,-32768, -5, 18, 30,-32768, 1, 1089, - 77, 77,-32768,-32768,-32768,-32768,-32768, 8,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768, 147, 6, 67,-32768, 34, 48,-32768,-32768, - -74,-32768,-32768,-32768,-32768,-32768, 1261,-32768, 148, 80, - 174, 159,-32768,-32768,-32768,-32768, 1127, 1165,-32768, 71, - 126,-32768,-32768, -74, -55, 79, 899,-32768,-32768,-32768, - 1127,-32768, 135, 1203, 28, 154, 40,-32768,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 1127, - 1127, 1127, 1127, 1127, 1127, 1127, 1127,-32768,-32768, 1127, - 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, - 1127, 1127, 1127,-32768, 40,-32768, 46, 91,-32768,-32768, --32768,-32768,-32768,-32768,-32768, -76,-32768, 116, 145, 191, - 156, 192, 170, 193, 173, 194, 196, 197, 177, 201, - 199, 780,-32768, 1127, 456,-32768, 1127, 937,-32768, 97, - 100, 621,-32768,-32768, 8,-32768, 621, 621,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 621, 1089, - 98, 99,-32768, 621, 106, 101, 188, 104, 105, 108, - 621, 113, 114, 115, 117, 118, 119, 124, 621, 621, - 621, 621, 127, 1089, 1127, 1127, 1127,-32768, 213,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 136, - 137, 138, 975, 820, 228, 1165, 140, 141, 143, 144, --32768,-32768, -73, 1127, -52, -74,-32768, 34,-32768, 139, - 149, 1013,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - 1165,-32768,-32768,-32768,-32768, 150,-32768, 152, 621, 243, - 244, 155, 621, 151, 1127, 1127, 1127, 1127, 155, 1127, - 1127, 1127, 1127, 1127, 1127, 1127, 157, 160, 161, 162, - 1127, 621, 621, 163, 164,-32768, 1165, 1165, 1165,-32768, --32768, -58,-32768, -18,-32768, -50, 1165, 1165, 1165, 1165, --32768, -27,-32768,-32768,-32768, 1051,-32768,-32768, -29, 240, - 241, 176, 621, 621, 1127,-32768, 165, 621,-32768, 166, - 175,-32768,-32768, 621, 178,-32768, 179, 184,-32768,-32768, - 621, 621, 621, 621,-32768, 181,-32768, 1127, 1127, 155, - 229, 187,-32768, 1165,-32768,-32768, 195, 198, 203, 208, --32768,-32768,-32768,-32768, 621, 621, 1127,-32768,-32768,-32768, - 209, 621, 210, 1127, 1127, 155, 1127, 1127, 1127,-32768, --32768,-32768,-32768, 1127, 621,-32768, 153, 1127, 1165,-32768, - 1165, 1165, 1165, 1165, 211, 180, 209, 183, 1127, 158, - 621,-32768,-32768,-32768, 215, 216,-32768, 204,-32768,-32768, - 206, 217, 220, 225, 226, 227, 247, 5, 254,-32768, --32768, 200, 1127, 1127,-32768,-32768, 1165,-32768,-32768,-32768, --32768, 621,-32768, 701, 14, 256,-32768,-32768,-32768, 231, --32768, 230,-32768, 701, 621,-32768, 277, 232, 242, 621, - 294, 301,-32768, 621, 621,-32768,-32768, 264, 346,-32768 +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "ESINT64VAL", "EUINT64VAL", "SINTVAL", + "UINTVAL", "FPVAL", "VOID", "BOOL", "SBYTE", "UBYTE", "SHORT", "USHORT", + "INT", "UINT", "LONG", "ULONG", "FLOAT", "DOUBLE", "TYPE", "LABEL", + "VAR_ID", "LABELSTR", "STRINGCONSTANT", "IMPLEMENTATION", + "ZEROINITIALIZER", "TRUETOK", "FALSETOK", "BEGINTOK", "ENDTOK", + "DECLARE", "GLOBAL", "CONSTANT", "SECTION", "VOLATILE", "FIXED", "TO", + "DOTDOTDOT", "NULL_TOK", "UNDEF", "CONST", "INTERNAL", "LINKONCE", + "WEAK", "APPENDING", "OPAQUE", "NOT", "EXTERNAL", "TARGET", "TRIPLE", + "ENDIAN", "POINTERSIZE", "LITTLE", "BIG", "ALIGN", "DEPLIBS", "CALL", + "TAIL", "CC_TOK", "CCC_TOK", "FASTCC_TOK", "COLDCC_TOK", "VECTOR", "OF", + "RET", "BR", "SWITCH", "INVOKE", "UNWIND", "UNREACHABLE", "ADD", "SUB", + "MUL", "DIV", "REM", "AND", "OR", "XOR", "SETLE", "SETGE", "SETLT", + "SETGT", "SETEQ", "SETNE", "VSETLE", "VSETGE", "VSETLT", "VSETGT", + "VSETEQ", "VSETNE", "MALLOC", "ALLOCA", "FREE", "LOAD", "STORE", + "GETELEMENTPTR", "PHI_TOK", "CAST", "SELECT", "VSELECT", "SHL", "SHR", + "VAARG", "VGATHER", "VIMM", "VSCATTER", "EXTRACT", "EXTRACTELEMENT", + "COMBINE", "COMBINEELEMENT", "VAARG_old", "VANEXT_old", "'='", "','", + "'\\\\'", "'('", "')'", "'['", "'x'", "']'", "'{'", "'}'", "'*'", "'c'", + "'<'", "'>'", "$accept", "INTVAL", "EINT64VAL", "ArithmeticOps", + "LogicalOps", "SetCondOps", "VSetCondOps", "ShiftOps", "SIntType", + "UIntType", "IntType", "FPType", "OptAssign", "OptLinkage", + "OptCallingConv", "OptAlign", "OptCAlign", "SectionString", + "OptSection", "GlobalVarAttributes", "GlobalVarAttribute", "TypesV", + "UpRTypesV", "Types", "PrimType", "UpRTypes", "TypeListI", + "ArgTypeListI", "ConstVal", "ConstExpr", "ConstVector", "GlobalType", + "Module", "FunctionList", "ConstPool", "@1", "@2", "BigOrLittle", + "TargetDefinition", "LibrariesDefinition", "LibList", "Name", "OptName", + "ArgVal", "ArgListH", "ArgList", "FunctionHeaderH", "BEGIN", + "FunctionHeader", "END", "Function", "FunctionProto", "@3", + "ConstValueRef", "SymbolicValueRef", "ValueRef", "ResolvedVal", + "BasicBlockList", "BasicBlock", "InstructionList", "BBTerminatorInst", + "JumpTable", "Inst", "PHIList", "ValueRefList", "ValueRefListE", + "OptTailCall", "InstVal", "IndexList", "OptVolatile", "OptFixed", + "MemoryInst", 0 }; +#endif -static const short yypgoto[] = {-32768, --32768, 270, 272, 279,-32768, 280, -105, -103, -404,-32768, - 324, 340, -98, -35,-32768, -26,-32768, -57, 262,-32768, - -86, 182, -221, 320,-32768,-32768,-32768,-32768,-32768,-32768, --32768, 2,-32768, 27,-32768,-32768, 344,-32768,-32768,-32768, --32768, 364,-32768, -416, 202, 146, 10,-32768, 355,-32768, --32768,-32768,-32768,-32768, 24, -34,-32768,-32768, -276,-32768, --32768,-32768 +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 61, 44, 92, 40, 41, 91, 120, + 93, 123, 125, 42, 99, 60, 62 }; +# endif +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 127, 128, 128, 129, 129, 130, 130, 130, 130, + 130, 131, 131, 131, 132, 132, 132, 132, 132, 132, + 133, 133, 133, 133, 133, 133, 134, 134, 135, 135, + 135, 135, 136, 136, 136, 136, 137, 137, 138, 138, + 139, 139, 140, 140, 140, 140, 140, 141, 141, 141, + 141, 141, 142, 142, 143, 143, 144, 145, 145, 146, + 146, 147, 147, 148, 148, 149, 149, 150, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 151, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 153, 153, 154, 154, 154, 154, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 156, 156, 156, 156, 156, 156, + 156, 157, 157, 158, 158, 159, 160, 160, 160, 160, + 161, 161, 162, 161, 163, 161, 161, 161, 161, 164, + 164, 165, 165, 165, 166, 167, 167, 167, 168, 168, + 169, 169, 170, 171, 171, 172, 172, 172, 172, 173, + 174, 174, 175, 176, 176, 177, 179, 178, 180, 180, + 180, 180, 180, 180, 180, 180, 180, 181, 181, 182, + 182, 183, 184, 184, 185, 186, 186, 186, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 188, 188, 189, + 190, 190, 191, 191, 192, 192, 193, 193, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 195, 195, 196, 196, 197, 197, 198, + 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198 +}; -#define YYLAST 1371 - +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 0, 1, 1, 1, 1, 0, 0, 1, 1, + 1, 2, 0, 2, 0, 3, 2, 0, 1, 0, + 3, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 4, 5, 5, 6, 3, + 2, 2, 1, 3, 1, 3, 1, 0, 4, 3, + 3, 4, 4, 3, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 6, 5, 8, 6, 6, 6, + 6, 3, 1, 1, 1, 1, 2, 2, 2, 1, + 4, 2, 0, 7, 0, 7, 3, 4, 0, 1, + 1, 3, 3, 3, 3, 3, 1, 0, 1, 1, + 1, 0, 2, 3, 1, 1, 3, 1, 0, 8, + 1, 1, 3, 1, 1, 2, 0, 3, 1, 1, + 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, + 1, 2, 2, 2, 3, 2, 0, 1, 2, 2, + 3, 9, 9, 8, 13, 1, 1, 6, 5, 2, + 6, 7, 1, 3, 1, 0, 2, 1, 5, 5, + 5, 5, 2, 4, 4, 6, 6, 4, 4, 4, + 2, 7, 1, 2, 0, 1, 0, 1, 0, 3, + 6, 3, 6, 2, 4, 6, 4, 4, 5, 8, + 4, 8, 6, 6 +}; -static const short yytable[] = { 69, - 207, 183, 208, 19, 84, 28, 74, 94, 210, 90, - -113, 28, 31, 69, 199, 200, 201, 202, 203, 204, - 205, 206, 353, 199, 200, 201, 202, 203, 204, 205, - 206, 19, 324, 454, 326, 3, 197, 462, -53, 94, - 238, 4, 39, 331, 239, 98, 98, 468, 198, 43, - 464, 5, 6, 7, 8, 14, 234, 15, 373, 339, - 167, 182, 374, 186, 333, 187, 91, 98, 96, 45, - 374, 46, 47, 376, 92, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 14, 381, - 15, 374, 98, 407, 384, 75, 22, 23, 24, 25, - 375, 32, 374, 211, 212, 79, 214, 215, 85, 86, - 193, 62, 40, 196, 221, 82, 35, 36, 37, 424, - -54, 453, 229, 230, 231, 232, 263, 265, 80, 266, - 463, 161, 162, 5, 6, 7, 8, 235, 236, 41, - 81, 213, 240, 241, 217, 218, 219, -30, -30, 220, - 89, 222, 223, 224, 225, 226, 227, 228, -29, -29, - 97, 268, 233, 199, 200, 201, 202, 203, 204, 205, - 206, 160, -28, -28, 289, -27, -27, 164, 63, 242, - 243, 64, 165, 69, 65, 93, 184, 185, -40, 194, - 14, 188, 15, 237, -34, -33, -32, -31, 312, 4, - -40, -40, -37, -38, 245, 246, 332, 69, 313, -40, - -40, -40, -40, 273, 266, -40, 16, 272, 290, 291, - 293, 294, 17, 295, 296, 297, 182, 182, 298, 182, - 370, 371, 372, 300, 301, 302, 316, 303, 304, 305, - 377, 378, 379, 380, 306, 314, 315, 311, 317, 318, - 319, 325, 327, 328, 182, 329, 330, 343, 344, 336, - 385, 386, 337, 479, 408, 348, 430, 452, 349, 334, - 340, 352, 341, 354, 441, 345, 465, 361, 359, 360, - 362, 363, 364, 368, 369, 392, 394, 410, 387, 456, - 182, 182, 182, 404, 438, 395, 439, 470, 397, 398, - 182, 182, 182, 182, 399, 350, 351, 409, 472, 268, - 355, 356, 357, 358, 474, 411, 457, 445, 412, 446, - 365, 475, 432, 413, 433, 434, 435, 436, 414, 419, - 421, 437, 207, 448, 208, 443, 444, 447, 449, 450, - 451, 405, 286, 287, 466, 480, 149, 182, 150, 207, - 467, 208, 471, 77, 288, 151, 153, 42, 190, 292, - 460, 88, 383, 261, 44, 20, 299, 34, 391, 428, - 0, 0, 0, 0, 307, 308, 309, 310, 406, 0, - 0, 431, 182, 262, 182, 182, 182, 182, 0, 0, - 0, 0, 0, 284, 0, 0, 0, 0, 284, 284, - 0, 0, 0, 422, 423, 0, 425, 426, 427, 0, - 284, 0, 0, 0, 0, 284, 0, 0, 0, 0, - 182, 0, 284, 0, 0, 0, 0, 0, 440, 0, - 284, 284, 284, 284, 342, 0, 0, 0, 347, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 458, 459, 0, 0, 0, 366, 367, 264, - 46, 47, 0, 92, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 14, 0, 15, - 0, 0, 0, 0, 0, 0, 0, 0, 388, 389, - 284, 0, 0, 393, 284, 0, 0, 0, 0, 396, - 62, 0, 0, 0, 0, 0, 400, 401, 402, 403, - 0, 0, 0, 284, 284, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 415, 416, 0, 0, 0, 0, 0, 420, 0, 0, - 0, 0, 0, 0, 284, 284, 0, 0, 0, 284, - 429, 0, 0, 0, 0, 284, 0, 0, 0, 0, - 0, 0, 284, 284, 284, 284, 442, 63, 0, 0, - 64, 0, 0, 65, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 284, 284, 0, 0, - 0, 0, 0, 284, 0, 0, 0, 461, 0, 0, - 0, 0, 0, 0, 0, 0, 284, 0, 0, 0, - 469, 0, 0, 0, 0, 473, 0, 0, 0, 476, - 477, 0, 284, 274, 275, 46, 47, 276, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 14, 0, 15, 0, 0, 277, 278, 0, - 0, 0, 0, 284, 0, 0, 0, 0, 279, 280, - 0, 0, 0, 0, 0, 0, 284, 0, 0, 0, - 0, 284, 0, 0, 0, 284, 284, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, - 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 274, 275, 0, 0, 276, 0, 0, - 0, 0, 0, 0, 250, 0, 251, 252, 0, 138, - 139, 0, 0, 0, 0, 0, 0, 277, 278, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 279, 280, - 0, 0, 0, 281, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, - 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 0, 46, 47, 0, 0, 0, 0, - 0, 0, 0, 0, 250, 0, 251, 252, 0, 138, - 139, 14, 0, 15, 0, 247, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 248, 249, 0, - 0, 0, 0, 281, 46, 47, 0, 92, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 60, - 61, 14, 0, 15, 0, 0, 0, 0, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 0, 0, 62, 0, 0, 0, 0, 0, - 0, 0, 0, 250, 0, 251, 252, 0, 138, 139, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 253, 0, 0, 254, 0, 0, - 0, 255, 256, 46, 47, 0, 92, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 14, 0, 15, 0, 0, 0, 0, 0, 0, 0, - 0, 63, 0, 0, 64, 189, 0, 65, 323, 0, - 0, 46, 47, 62, 92, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 14, 0, - 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 267, 0, 0, 0, 0, 0, 46, - 47, 62, 92, 168, 169, 170, 171, 172, 173, 174, - 175, 176, 177, 178, 60, 61, 14, 0, 15, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 63, 0, 0, 64, 0, 0, 65, 46, 47, 62, - 92, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 14, 0, 15, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 63, 338, - 0, 64, 0, 0, 65, 46, 47, 62, 92, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 14, 0, 15, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 63, 382, 0, 64, - 0, 320, 65, 46, 47, 62, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 14, 0, 15, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 63, 0, 0, 64, 0, 0, - 65, 46, 47, 62, 92, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 14, 0, - 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 63, 0, 0, 64, 0, 0, 65, 46, - 47, 62, 92, 168, 169, 170, 171, 172, 173, 174, - 175, 176, 177, 178, 60, 61, 14, 0, 15, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 63, 0, 0, 64, 0, 0, 65, 46, 47, 62, - 195, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 14, 0, 15, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, - 0, 64, 0, 0, 65, 0, 0, 62, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 63, 0, 0, 64, - 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 99, 100, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, - 0, 0, 0, 0, 63, 102, 103, 64, 0, 0, - 65, 0, 0, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 0, 0, 133, 134, 135, 136, 137, 138, - 139, 140, 141, -214, 142, 143, 144, 145, 146, 147, - 148 +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned char yydefact[] = +{ + 138, 0, 46, 129, 1, 128, 166, 42, 43, 44, + 45, 47, 186, 126, 127, 186, 148, 149, 0, 0, + 46, 0, 131, 47, 0, 48, 49, 50, 0, 0, + 187, 183, 41, 163, 164, 165, 182, 0, 0, 0, + 136, 0, 0, 0, 0, 40, 167, 51, 2, 3, + 64, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 0, 0, 0, 177, 0, + 0, 63, 82, 67, 178, 83, 160, 161, 162, 226, + 185, 0, 0, 0, 147, 137, 130, 123, 124, 0, + 0, 84, 0, 0, 66, 90, 92, 0, 0, 97, + 91, 225, 227, 0, 207, 0, 0, 0, 0, 47, + 195, 196, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 184, 47, 199, 0, + 0, 222, 143, 140, 139, 141, 142, 146, 0, 134, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 0, 0, 0, 0, 132, 0, 0, 0, 89, + 158, 96, 94, 0, 0, 212, 206, 189, 188, 0, + 0, 31, 35, 30, 34, 29, 33, 28, 32, 36, + 37, 0, 0, 54, 54, 233, 0, 0, 220, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 144, 59, 111, 112, 4, 5, 109, 110, 113, + 108, 104, 105, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 107, 106, 59, 65, 0, 65, + 93, 157, 151, 154, 155, 0, 0, 85, 168, 169, + 170, 171, 172, 173, 174, 0, 176, 180, 179, 181, + 0, 190, 0, 0, 0, 229, 0, 231, 224, 0, + 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 145, 0, 135, 0, 0, 0, 99, 122, + 0, 103, 0, 100, 0, 0, 0, 0, 0, 133, + 86, 65, 87, 150, 152, 0, 57, 95, 0, 0, + 0, 0, 0, 0, 0, 0, 236, 0, 0, 214, + 0, 0, 217, 237, 0, 0, 240, 0, 0, 218, + 219, 0, 0, 0, 0, 213, 0, 234, 0, 0, + 0, 0, 61, 59, 224, 0, 0, 0, 98, 102, + 101, 0, 0, 0, 0, 88, 156, 153, 58, 52, + 175, 0, 0, 205, 54, 55, 54, 202, 223, 0, + 0, 0, 0, 224, 0, 0, 0, 208, 209, 210, + 211, 205, 0, 238, 56, 62, 60, 0, 0, 0, + 121, 0, 0, 0, 0, 0, 159, 0, 0, 204, + 0, 0, 230, 232, 0, 0, 0, 215, 216, 243, + 0, 0, 242, 0, 235, 115, 0, 0, 0, 0, + 0, 0, 53, 0, 0, 0, 203, 200, 0, 0, + 0, 221, 114, 0, 117, 118, 119, 120, 0, 193, + 0, 0, 0, 201, 239, 241, 0, 191, 0, 192, + 0, 0, 116, 0, 0, 0, 0, 0, 0, 198, + 0, 0, 197, 194 }; -static const short yycheck[] = { 26, - 106, 88, 106, 2, 40, 23, 29, 65, 107, 4, - 0, 23, 30, 40, 10, 11, 12, 13, 14, 15, - 16, 17, 299, 10, 11, 12, 13, 14, 15, 16, - 17, 30, 254, 438, 256, 25, 9, 454, 113, 97, - 117, 31, 111, 117, 121, 120, 120, 464, 21, 111, - 455, 41, 42, 43, 44, 22, 155, 24, 117, 281, - 87, 88, 121, 119, 117, 121, 61, 120, 67, 4, - 121, 5, 6, 124, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 117, - 24, 121, 120, 370, 124, 118, 57, 58, 59, 60, - 119, 119, 121, 130, 131, 111, 133, 134, 32, 33, - 101, 45, 20, 104, 141, 115, 49, 50, 51, 396, - 113, 117, 149, 150, 151, 152, 184, 185, 111, 187, - 117, 52, 53, 41, 42, 43, 44, 92, 93, 47, - 111, 132, 27, 28, 135, 136, 137, 3, 4, 140, - 4, 142, 143, 144, 145, 146, 147, 148, 3, 4, - 113, 188, 153, 10, 11, 12, 13, 14, 15, 16, - 17, 24, 3, 4, 210, 3, 4, 4, 112, 3, - 4, 115, 24, 210, 118, 119, 116, 62, 20, 55, - 22, 113, 24, 103, 4, 4, 4, 4, 234, 31, - 32, 33, 7, 7, 4, 7, 264, 234, 235, 41, - 42, 43, 44, 114, 272, 47, 48, 121, 121, 121, - 115, 121, 54, 36, 121, 121, 253, 254, 121, 256, - 317, 318, 319, 121, 121, 121, 24, 121, 121, 121, - 327, 328, 329, 330, 121, 236, 237, 121, 113, 113, - 113, 24, 113, 113, 281, 113, 113, 15, 15, 121, - 21, 21, 114, 0, 36, 115, 114, 21, 295, 268, - 121, 298, 121, 300, 117, 121, 21, 121, 305, 306, - 121, 121, 121, 121, 121, 121, 121, 374, 113, 36, - 317, 318, 319, 113, 115, 121, 114, 21, 121, 121, - 327, 328, 329, 330, 121, 296, 297, 121, 67, 336, - 301, 302, 303, 304, 21, 121, 117, 114, 121, 114, - 311, 21, 409, 121, 411, 412, 413, 414, 121, 121, - 121, 121, 438, 114, 438, 121, 121, 121, 114, 114, - 114, 368, 197, 198, 114, 0, 77, 374, 77, 455, - 121, 455, 121, 30, 209, 77, 77, 18, 97, 214, - 447, 42, 336, 182, 21, 2, 221, 13, 345, 404, - -1, -1, -1, -1, 229, 230, 231, 232, 369, -1, - -1, 408, 409, 182, 411, 412, 413, 414, -1, -1, - -1, -1, -1, 192, -1, -1, -1, -1, 197, 198, - -1, -1, -1, 394, 395, -1, 397, 398, 399, -1, - 209, -1, -1, -1, -1, 214, -1, -1, -1, -1, - 447, -1, 221, -1, -1, -1, -1, -1, 419, -1, - 229, 230, 231, 232, 289, -1, -1, -1, 293, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 443, 444, -1, -1, -1, 312, 313, 4, - 5, 6, -1, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, -1, 24, - -1, -1, -1, -1, -1, -1, -1, -1, 343, 344, - 289, -1, -1, 348, 293, -1, -1, -1, -1, 354, - 45, -1, -1, -1, -1, -1, 361, 362, 363, 364, - -1, -1, -1, 312, 313, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 385, 386, -1, -1, -1, -1, -1, 392, -1, -1, - -1, -1, -1, -1, 343, 344, -1, -1, -1, 348, - 405, -1, -1, -1, -1, 354, -1, -1, -1, -1, - -1, -1, 361, 362, 363, 364, 421, 112, -1, -1, - 115, -1, -1, 118, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 385, 386, -1, -1, - -1, -1, -1, 392, -1, -1, -1, 452, -1, -1, - -1, -1, -1, -1, -1, -1, 405, -1, -1, -1, - 465, -1, -1, -1, -1, 470, -1, -1, -1, 474, - 475, -1, 421, 3, 4, 5, 6, 7, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 22, -1, 24, -1, -1, 27, 28, -1, - -1, -1, -1, 452, -1, -1, -1, -1, 38, 39, - -1, -1, -1, -1, -1, -1, 465, -1, -1, -1, - -1, 470, -1, -1, -1, 474, 475, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 3, 4, -1, -1, 7, -1, -1, - -1, -1, -1, -1, 94, -1, 96, 97, -1, 99, - 100, -1, -1, -1, -1, -1, -1, 27, 28, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 38, 39, - -1, -1, -1, 123, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, -1, 5, 6, -1, -1, -1, -1, - -1, -1, -1, -1, 94, -1, 96, 97, -1, 99, - 100, 22, -1, 24, -1, 26, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 38, 39, -1, - -1, -1, -1, 123, 5, 6, -1, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, -1, 24, -1, -1, -1, -1, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, -1, -1, 45, -1, -1, -1, -1, -1, - -1, -1, -1, 94, -1, 96, 97, -1, 99, 100, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 115, -1, -1, 118, -1, -1, - -1, 122, 123, 5, 6, -1, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, -1, 24, -1, -1, -1, -1, -1, -1, -1, - -1, 112, -1, -1, 115, 37, -1, 118, 119, -1, - -1, 5, 6, 45, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, -1, - 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 37, -1, -1, -1, -1, -1, 5, - 6, 45, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, -1, 24, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 112, -1, -1, 115, -1, -1, 118, 5, 6, 45, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, -1, 24, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 112, 37, - -1, 115, -1, -1, 118, 5, 6, 45, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, -1, 24, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 112, 37, -1, 115, - -1, 117, 118, 5, 6, 45, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, -1, 24, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 112, -1, -1, 115, -1, -1, - 118, 5, 6, 45, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, -1, - 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 112, -1, -1, 115, -1, -1, 118, 5, - 6, 45, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, -1, 24, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 112, -1, -1, 115, -1, -1, 118, 5, 6, 45, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, -1, 24, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 112, -1, - -1, 115, -1, -1, 118, -1, -1, 45, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 112, -1, -1, 115, - -1, -1, 118, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 34, 35, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 46, -1, -1, -1, - -1, -1, -1, -1, 112, 55, 56, 115, -1, -1, - 118, -1, -1, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, -1, -1, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110 +/* YYDEFGOTO[NTERM-NUM]. */ +static const short yydefgoto[] = +{ + -1, 68, 247, 260, 261, 262, 154, 263, 181, 182, + 211, 183, 20, 11, 28, 436, 295, 382, 399, 324, + 383, 69, 70, 194, 72, 73, 97, 193, 329, 286, + 330, 89, 1, 2, 3, 266, 242, 165, 40, 85, + 168, 74, 344, 273, 274, 275, 29, 78, 12, 35, + 13, 14, 23, 287, 75, 289, 407, 15, 31, 32, + 156, 481, 80, 218, 439, 440, 157, 158, 356, 159, + 160, 161 }; -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "/usr/share/bison.simple" -/* This file comes from bison-1.28. */ -/* Skeleton output parser for bison, - Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -376 +static const short yypact[] = +{ + -376, 11, 112, 145, -376, -376, -376, -376, -376, -376, + -376, 90, 13, -376, -376, 19, -376, -376, 120, -47, + -4, -13, -376, 90, 92, -376, -376, -376, 1094, -23, + -376, -376, 142, -376, -376, -376, -376, 9, 33, 40, + -376, 0, 1094, 98, 98, -376, -376, -376, -376, -376, + 47, -376, -376, -376, -376, -376, -376, -376, -376, -376, + -376, -376, -376, -376, -376, 131, 5, 64, -376, 142, + 52, -376, -376, -56, -376, -376, -376, -376, -376, 1270, + -376, 149, 86, 171, 159, -376, -376, -376, -376, 1133, + 1172, -376, 81, 146, -376, -376, -56, -20, 97, 860, + -376, -376, -376, 1133, -376, 158, 1211, 82, 316, 90, + -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, + -376, -376, -376, -376, -376, -376, -376, -376, -376, -376, + -376, -376, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, + -376, -376, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, + 1133, 1133, 1133, 1133, 1133, 1133, -376, 90, -376, 65, + 115, -376, -376, -376, -376, -376, -376, -376, -19, -376, + 153, 188, 217, 192, 219, 199, 220, 201, 221, 223, + 225, 203, 229, 227, 719, -376, 1133, 485, 1133, -376, + 899, -376, 113, 118, 571, -376, -376, 47, -376, 571, + 571, -376, -376, -376, -376, -376, -376, -376, -376, -376, + -376, 571, 1094, 122, 123, -376, 571, 124, 127, 206, + 130, 132, 133, 571, 138, 139, 141, 144, 147, 148, + 151, 571, 571, 571, 571, 152, 1094, 1133, 1133, 1133, + 232, -376, 154, -376, -376, -376, -376, -376, -376, -376, + -376, -376, -376, 129, 143, 155, 977, 840, 236, 1172, + 156, 161, 163, 164, -376, -376, 154, -3, 1133, 22, + -56, -376, 142, -376, 168, 150, 1016, -376, -376, -376, + -376, -376, -376, -376, -376, 1172, -376, -376, -376, -376, + 173, -376, 175, 571, 35, -376, 37, -376, 176, 571, + 157, 1133, 1133, 1133, 1133, 176, 1133, 1133, 1133, 1133, + 1133, 1133, 1133, 177, 178, 180, 181, 1133, 571, 571, + 182, 191, -376, 59, -376, 1172, 1172, 1172, -376, -376, + 24, -376, -1, -376, -17, 1172, 1172, 1172, 1172, -376, + -376, 38, -376, -376, -376, 1055, 251, -376, -15, 242, + 285, 195, 571, 308, 571, 1133, -376, 200, 571, -376, + 202, 204, -376, -376, 571, 205, -376, 208, 222, -376, + -376, 571, 571, 571, 571, -376, 197, -376, 1133, 1133, + 291, 330, -376, 154, 176, 298, 224, 1172, -376, -376, + -376, 226, 234, 235, 237, -376, -376, -376, -376, 282, + -376, 571, 571, 1133, 238, -376, 238, -376, 240, 571, + 241, 1133, 1133, 176, 1133, 1133, 1133, -376, -376, -376, + -376, 1133, 571, -376, -376, -376, -376, 239, 1133, 1172, + -376, 1172, 1172, 1172, 1172, 335, -376, 246, 243, 240, + 245, 286, -376, -376, 1133, 244, 571, -376, -376, -376, + 252, 253, -376, 248, -376, -376, 254, 256, 255, 259, + 260, 263, -376, 322, 8, 331, -376, -376, 261, 1133, + 1133, -376, -376, 1172, -376, -376, -376, -376, 571, -376, + 655, 16, 352, -376, -376, -376, 265, -376, 269, -376, + 655, 571, -376, 363, 271, 318, 571, 369, 370, -376, + 571, 571, -376, -376 +}; - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. +/* YYPGOTO[NTERM-NUM]. */ +static const short yypgoto[] = +{ + -376, -376, -376, 313, 314, 315, -376, 317, -107, -106, + -375, -376, 365, 375, -92, -376, -207, 53, -376, -256, + -376, -38, -376, -28, -376, -54, 299, -376, -87, 218, + -222, 364, -376, -376, -376, -376, -376, -376, -376, -376, + -376, 2, -376, 62, -376, -376, 386, -376, -376, -376, + -376, 407, -376, -361, 70, 215, -91, -376, 396, -376, + -376, -376, -376, -376, 57, -8, -376, -376, -297, -376, + -376, -376 +}; - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -229 +static const short yytable[] = +{ + 71, 209, 210, 185, 86, 21, 76, 297, 363, 92, + 339, 4, 195, 96, 71, 198, 42, 212, 201, 202, + 203, 204, 205, 206, 207, 208, 201, 202, 203, 204, + 205, 206, 207, 208, 21, 332, 30, 334, 7, 8, + 9, 10, 30, 215, 43, 96, 219, 220, 221, 33, + 352, 222, 354, 224, 225, 226, 227, 228, 229, 230, + -65, 169, 184, 348, 235, 236, 41, 100, 93, 48, + 49, 98, 94, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 16, 427, 17, 480, + 353, 199, 353, 380, 188, 240, 47, 387, 77, 387, + 45, 241, 189, 200, 213, 214, 490, 216, 217, 390, + 64, 400, -125, 387, 381, 223, 449, 340, 84, 488, + 100, 389, 81, 231, 232, 233, 234, 426, 479, 494, + 87, 88, 267, 269, 270, 91, 489, 5, 387, 163, + 164, 34, 342, 6, 388, 100, 82, 320, 321, 24, + 25, 26, 27, 83, 7, 8, 9, 10, 395, 237, + 238, 100, 272, -66, 16, -41, 17, 16, 99, 17, + 37, 38, 39, 162, 293, 166, 6, -41, -41, 65, + 243, 244, 66, 167, 71, 67, 95, -41, -41, -41, + -41, -31, -31, -41, 18, -30, -30, 442, 318, 443, + 186, 19, -29, -29, -28, -28, 245, 246, 71, 319, + 187, 360, 361, 190, 341, 196, 365, 366, 367, 368, + 239, -35, 270, -34, -33, -32, 375, 276, 184, 184, + -38, 184, -39, 248, 249, 277, 294, 296, 384, 385, + 386, 300, 299, 301, 302, 325, 303, 304, 391, 392, + 393, 394, 306, 307, 265, 308, 322, 184, 309, 326, + 333, 310, 311, 401, 288, 312, 317, 346, 323, 288, + 288, 327, 335, 359, 343, 358, 362, 336, 364, 337, + 338, 288, 345, 369, 370, 380, 288, 349, 423, 350, + 355, 371, 372, 288, 373, 374, 378, 184, 184, 184, + 430, 288, 288, 288, 288, 379, 402, 184, 184, 184, + 184, 403, 405, 421, 409, 424, 411, 272, 412, 414, + 447, 448, 415, 450, 451, 452, 201, 202, 203, 204, + 205, 206, 207, 208, 425, 428, 416, 435, 429, 462, + 431, 353, 457, 478, 458, 459, 460, 461, 432, 433, + 422, 434, 441, 466, 444, 446, 455, 209, 210, 184, + 463, 464, 465, 288, 467, 471, 469, 470, 482, 288, + 473, 472, 474, 491, 209, 210, 475, 476, 484, 485, + 477, 483, 492, 493, 496, 497, 486, 498, 288, 288, + 500, 501, 151, 152, 153, 44, 155, 79, 192, 398, + 456, 184, 264, 184, 184, 184, 184, 397, 90, 46, + 22, 36, 408, 453, 290, 291, 0, 0, 0, 0, + 0, 0, 288, 0, 288, 0, 292, 0, 288, 0, + 0, 298, 0, 0, 288, 0, 0, 0, 305, 0, + 0, 288, 288, 288, 288, 184, 313, 314, 315, 316, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 288, 288, 0, 0, 0, 0, 0, 0, 288, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, + 48, 49, 288, 94, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 16, 351, 17, + 0, 0, 0, 0, 357, 0, 288, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 64, 0, 376, 377, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 288, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 288, 0, 0, 0, 0, 288, 404, 0, 406, + 288, 288, 0, 410, 278, 279, 48, 49, 280, 413, + 0, 0, 0, 0, 0, 0, 417, 418, 419, 420, + 0, 0, 0, 16, 0, 17, 0, 0, 281, 282, + 65, 0, 0, 66, 0, 0, 67, 0, 0, 0, + 283, 284, 0, 0, 0, 0, 437, 438, 0, 0, + 0, 0, 0, 0, 445, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 454, 0, 0, + 0, 0, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 0, 0, 278, 279, + 0, 468, 280, 0, 0, 0, 0, 253, 0, 254, + 255, 0, 140, 141, 0, 0, 0, 0, 0, 0, + 0, 0, 281, 282, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 487, 283, 284, 285, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 495, 0, 0, 0, + 0, 499, 0, 0, 0, 502, 503, 0, 0, 0, + 0, 0, 0, 0, 48, 49, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 0, 16, 0, 17, 0, 250, 0, 0, 0, 0, + 0, 253, 0, 254, 255, 0, 140, 141, 251, 252, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 285, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 253, 0, 254, 255, 0, + 140, 141, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 256, 0, 0, + 257, 0, 0, 258, 259, 48, 49, 0, 94, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 62, 63, 16, 0, 17, 48, 49, 0, 94, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 16, 0, 17, 0, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 191, 0, + 0, 0, 0, 0, 48, 49, 64, 94, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 16, 0, 17, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 271, 0, 0, + 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 65, 0, 0, 66, 0, + 0, 67, 331, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 65, 0, 0, 66, 0, + 0, 67, 48, 49, 0, 94, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 62, 63, 16, + 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 65, 0, 0, 66, 0, 0, + 67, 48, 49, 64, 94, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 16, 0, + 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 347, 0, 0, 0, 0, 0, + 48, 49, 64, 94, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 16, 0, 17, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 65, 396, 0, 66, 0, 328, 67, 48, + 49, 64, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 16, 0, 17, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 65, 0, 0, 66, 0, 0, 67, 48, 49, + 64, 94, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 16, 0, 17, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 65, 0, 0, 66, 0, 0, 67, 48, 49, 64, + 94, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 62, 63, 16, 0, 17, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, + 0, 0, 66, 0, 0, 67, 48, 49, 64, 197, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 16, 0, 17, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, + 0, 66, 0, 0, 67, 0, 0, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, + 66, 0, 0, 67, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 101, 102, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 103, 0, 0, + 0, 0, 0, 0, 0, 0, 65, 104, 105, 66, + 0, 0, 67, 0, 0, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 0, 0, 135, 136, 137, 138, + 139, 140, 141, 142, 143, -228, 144, 145, 146, 147, + 148, 149, 150 +}; - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ +static const short yycheck[] = +{ + 28, 108, 108, 90, 42, 3, 29, 214, 305, 4, + 266, 0, 103, 67, 42, 106, 20, 109, 10, 11, + 12, 13, 14, 15, 16, 17, 10, 11, 12, 13, + 14, 15, 16, 17, 32, 257, 23, 259, 42, 43, + 44, 45, 23, 134, 48, 99, 137, 138, 139, 30, + 15, 142, 15, 144, 145, 146, 147, 148, 149, 150, + 116, 89, 90, 285, 155, 157, 113, 123, 63, 5, + 6, 69, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 384, 24, 464, + 55, 9, 55, 34, 114, 114, 4, 114, 121, 114, + 113, 120, 122, 21, 132, 133, 481, 135, 136, 126, + 46, 126, 0, 114, 55, 143, 413, 120, 118, 480, + 123, 122, 113, 151, 152, 153, 154, 383, 120, 490, + 32, 33, 186, 187, 188, 4, 120, 25, 114, 53, + 54, 122, 120, 31, 120, 123, 113, 238, 239, 59, + 60, 61, 62, 113, 42, 43, 44, 45, 120, 94, + 95, 123, 190, 116, 22, 20, 24, 22, 116, 24, + 50, 51, 52, 24, 212, 4, 31, 32, 33, 115, + 27, 28, 118, 24, 212, 121, 122, 42, 43, 44, + 45, 3, 4, 48, 49, 3, 4, 404, 236, 406, + 119, 56, 3, 4, 3, 4, 3, 4, 236, 237, + 64, 302, 303, 116, 268, 57, 307, 308, 309, 310, + 105, 4, 276, 4, 4, 4, 317, 114, 256, 257, + 7, 259, 7, 4, 7, 117, 114, 114, 325, 326, + 327, 114, 118, 37, 114, 116, 114, 114, 335, 336, + 337, 338, 114, 114, 184, 114, 24, 285, 114, 116, + 24, 114, 114, 21, 194, 114, 114, 117, 114, 199, + 200, 116, 116, 301, 272, 118, 304, 116, 306, 116, + 116, 211, 114, 311, 312, 34, 216, 114, 379, 114, + 114, 114, 114, 223, 114, 114, 114, 325, 326, 327, + 387, 231, 232, 233, 234, 114, 21, 335, 336, 337, + 338, 116, 4, 116, 114, 24, 114, 345, 114, 114, + 411, 412, 114, 414, 415, 416, 10, 11, 12, 13, + 14, 15, 16, 17, 4, 37, 114, 55, 114, 4, + 114, 55, 429, 21, 431, 432, 433, 434, 114, 114, + 378, 114, 114, 444, 114, 114, 117, 464, 464, 387, + 114, 118, 117, 293, 120, 117, 114, 114, 37, 299, + 114, 117, 117, 21, 481, 481, 117, 117, 469, 470, + 117, 120, 117, 114, 21, 114, 473, 69, 318, 319, + 21, 21, 79, 79, 79, 20, 79, 32, 99, 346, + 428, 429, 184, 431, 432, 433, 434, 345, 44, 23, + 3, 15, 355, 421, 199, 200, -1, -1, -1, -1, + -1, -1, 352, -1, 354, -1, 211, -1, 358, -1, + -1, 216, -1, -1, 364, -1, -1, -1, 223, -1, + -1, 371, 372, 373, 374, 473, 231, 232, 233, 234, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 401, 402, -1, -1, -1, -1, -1, -1, 409, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, + 5, 6, 422, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 293, 24, + -1, -1, -1, -1, 299, -1, 446, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 46, -1, 318, 319, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 478, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 491, -1, -1, -1, -1, 496, 352, -1, 354, + 500, 501, -1, 358, 3, 4, 5, 6, 7, 364, + -1, -1, -1, -1, -1, -1, 371, 372, 373, 374, + -1, -1, -1, 22, -1, 24, -1, -1, 27, 28, + 115, -1, -1, 118, -1, -1, 121, -1, -1, -1, + 39, 40, -1, -1, -1, -1, 401, 402, -1, -1, + -1, -1, -1, -1, 409, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 422, -1, -1, + -1, -1, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, -1, -1, 3, 4, + -1, 446, 7, -1, -1, -1, -1, 96, -1, 98, + 99, -1, 101, 102, -1, -1, -1, -1, -1, -1, + -1, -1, 27, 28, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 478, 39, 40, 125, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 491, -1, -1, -1, + -1, 496, -1, -1, -1, 500, 501, -1, -1, -1, + -1, -1, -1, -1, 5, 6, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + -1, 22, -1, 24, -1, 26, -1, -1, -1, -1, + -1, 96, -1, 98, 99, -1, 101, 102, 39, 40, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 125, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 96, -1, 98, 99, -1, + 101, 102, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 118, -1, -1, + 121, -1, -1, 124, 125, 5, 6, -1, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, -1, 24, 5, 6, -1, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, -1, 24, -1, 46, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 38, -1, + -1, -1, -1, -1, 5, 6, 46, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, -1, 24, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 38, -1, -1, + -1, -1, -1, -1, -1, 46, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 115, -1, -1, 118, -1, + -1, 121, 122, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 115, -1, -1, 118, -1, + -1, 121, 5, 6, -1, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + -1, 24, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 115, -1, -1, 118, -1, -1, + 121, 5, 6, 46, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, -1, + 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 38, -1, -1, -1, -1, -1, + 5, 6, 46, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, -1, 24, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 115, 38, -1, 118, -1, 120, 121, 5, + 6, 46, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, -1, 24, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 115, -1, -1, 118, -1, -1, 121, 5, 6, + 46, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, -1, 24, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 115, -1, -1, 118, -1, -1, 121, 5, 6, 46, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, -1, 24, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 115, + -1, -1, 118, -1, -1, 121, 5, 6, 46, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, -1, 24, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 115, -1, + -1, 118, -1, -1, 121, -1, -1, 46, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 115, -1, -1, + 118, -1, -1, 121, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 35, 36, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 47, -1, -1, + -1, -1, -1, -1, -1, -1, 115, 57, 58, 118, + -1, -1, 121, -1, -1, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, -1, -1, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112 +}; -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 159, 160, 161, 0, 25, 31, 42, 43, 44, + 45, 140, 175, 177, 178, 184, 22, 24, 49, 56, + 139, 168, 178, 179, 59, 60, 61, 62, 141, 173, + 23, 185, 186, 30, 122, 176, 185, 50, 51, 52, + 165, 113, 20, 48, 140, 113, 173, 4, 5, 6, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 46, 115, 118, 121, 128, 148, + 149, 150, 151, 152, 168, 181, 29, 121, 174, 139, + 189, 113, 113, 113, 118, 166, 148, 32, 33, 158, + 158, 4, 4, 63, 8, 122, 152, 153, 168, 116, + 123, 35, 36, 47, 57, 58, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 106, 107, 108, 109, 110, 111, + 112, 130, 131, 132, 133, 134, 187, 193, 194, 196, + 197, 198, 24, 53, 54, 164, 4, 24, 167, 150, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 135, 136, 138, 150, 155, 119, 64, 114, 122, + 116, 38, 153, 154, 150, 183, 57, 8, 183, 9, + 21, 10, 11, 12, 13, 14, 15, 16, 17, 135, + 136, 137, 141, 150, 150, 183, 150, 150, 190, 183, + 183, 183, 183, 150, 183, 183, 183, 183, 183, 183, + 183, 150, 150, 150, 150, 183, 141, 94, 95, 105, + 114, 120, 163, 27, 28, 3, 4, 129, 4, 7, + 26, 39, 40, 96, 98, 99, 118, 121, 124, 125, + 130, 131, 132, 134, 156, 181, 162, 152, 4, 152, + 152, 38, 150, 170, 171, 172, 114, 117, 3, 4, + 7, 27, 28, 39, 40, 125, 156, 180, 181, 182, + 182, 182, 182, 148, 114, 143, 114, 143, 182, 118, + 114, 37, 114, 114, 114, 182, 114, 114, 114, 114, + 114, 114, 114, 182, 182, 182, 182, 114, 148, 150, + 183, 183, 24, 114, 146, 116, 116, 116, 120, 155, + 157, 122, 157, 24, 157, 116, 116, 116, 116, 146, + 120, 152, 120, 168, 169, 114, 117, 38, 157, 114, + 114, 182, 15, 55, 15, 114, 195, 182, 118, 150, + 183, 183, 150, 195, 150, 183, 183, 183, 183, 150, + 150, 114, 114, 114, 114, 183, 182, 182, 114, 114, + 34, 55, 144, 147, 155, 155, 155, 114, 120, 122, + 126, 155, 155, 155, 155, 120, 38, 170, 144, 145, + 126, 21, 21, 116, 182, 4, 182, 183, 191, 114, + 182, 114, 114, 182, 114, 114, 114, 182, 182, 182, + 182, 116, 150, 183, 24, 4, 146, 195, 37, 114, + 155, 114, 114, 114, 114, 55, 142, 182, 182, 191, + 192, 114, 143, 143, 114, 182, 114, 183, 183, 195, + 183, 183, 183, 192, 182, 117, 150, 155, 155, 155, + 155, 155, 4, 114, 118, 117, 183, 120, 182, 114, + 114, 117, 117, 114, 117, 117, 117, 117, 21, 120, + 137, 188, 37, 120, 183, 183, 155, 182, 180, 120, + 137, 21, 117, 114, 180, 182, 21, 114, 69, 182, + 21, 21, 182, 182 +}; -/* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -#ifndef YYSTACK_USE_ALLOCA -#ifdef alloca -#define YYSTACK_USE_ALLOCA -#else /* alloca not defined */ -#ifdef __GNUC__ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#else /* not GNU C. */ -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) -#define YYSTACK_USE_ALLOCA -#include -#else /* not sparc */ -/* We think this test detects Watcom and Microsoft C. */ -/* This used to test MSDOS, but that is a bad idea - since that symbol is in the user namespace. */ -#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) -#if 0 /* No need for malloc.h, which pollutes the namespace; - instead, just don't use alloca. */ -#include +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ #endif -#else /* not MSDOS, or __TURBOC__ */ -#if defined(_AIX) -/* I don't know what this was needed for, but it pollutes the namespace. - So I turned it off. rms, 2 May 1997. */ -/* #include */ - #pragma alloca -#define YYSTACK_USE_ALLOCA -#else /* not MSDOS, or __TURBOC__, or _AIX */ -#if 0 -#ifdef __hpux /* haible at ilog.fr says this works for HPUX 9.05 and up, - and on HPUX 10. Eventually we can turn this on. */ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#endif /* __hpux */ +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t #endif -#endif /* not _AIX */ -#endif /* not MSDOS, or __TURBOC__ */ -#endif /* not sparc */ -#endif /* not GNU C */ -#endif /* alloca not defined */ -#endif /* YYSTACK_USE_ALLOCA not defined */ - -#ifdef YYSTACK_USE_ALLOCA -#define YYSTACK_ALLOC alloca -#else -#define YYSTACK_ALLOC malloc +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int #endif - -/* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 +#define YYEMPTY (-2) #define YYEOF 0 + #define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab +#define YYABORT goto yyabortlab #define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. - This remains here temporarily to ease the - transition to the new meaning of YYERROR, for GCC. + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ + #define YYFAIL goto yyerrlab + #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(token, value) \ + +#define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ - { yychar = (token), yylval = (value); \ - yychar1 = YYTRANSLATE (yychar); \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK; \ goto yybackup; \ } \ else \ - { yyerror ("syntax error: cannot back up"); YYERROR; } \ + { \ + yyerror ("syntax error: cannot back up");\ + YYERROR; \ + } \ while (0) #define YYTERROR 1 #define YYERRCODE 256 -#ifndef YYPURE -#define YYLEX yylex() -#endif +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). */ -#ifdef YYPURE -#ifdef YYLSP_NEEDED -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval, &yylloc) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + Current.first_line = Rhs[1].first_line; \ + Current.first_column = Rhs[1].first_column; \ + Current.last_line = Rhs[N].last_line; \ + Current.last_column = Rhs[N].last_column; #endif -#else /* not YYLSP_NEEDED */ + +/* YYLEX -- calling `yylex' with the right arguments. */ + #ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, YYLEX_PARAM) +# define YYLEX yylex (YYLEX_PARAM) #else -#define YYLEX yylex(&yylval) -#endif -#endif /* not YYLSP_NEEDED */ +# define YYLEX yylex () #endif -/* If nonreentrant, generate the variables here */ +/* Enable debugging if requested. */ +#if YYDEBUG -#ifndef YYPURE +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ +} while (0) + +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (cinluded). | +`------------------------------------------------------------------*/ -#ifdef YYLSP_NEEDED -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short *bottom, short *top) +#else +static void +yy_stack_print (bottom, top) + short *bottom; + short *top; #endif +{ + YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} -int yynerrs; /* number of parse errors so far */ -#endif /* not YYPURE */ +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) -#if YYDEBUG != 0 -int yydebug; /* nonzero means print parse trace */ -/* Since this is uninitialized, it does not stop multiple parsers - from coexisting. */ + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_reduce_print (int yyrule) +#else +static void +yy_reduce_print (yyrule) + int yyrule; #endif +{ + int yyi; + unsigned int yylineno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + yyrule - 1, yylineno); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YYDSYMPRINT(Args) +# define YYDSYMPRINTF(Title, Token, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ -/* YYINITDEPTH indicates the initial size of the parser's stacks */ +/* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH -#define YYINITDEPTH 200 +# define YYINITDEPTH 200 #endif -/* YYMAXDEPTH is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ #if YYMAXDEPTH == 0 -#undef YYMAXDEPTH +# undef YYMAXDEPTH #endif #ifndef YYMAXDEPTH -#define YYMAXDEPTH 10000 +# define YYMAXDEPTH 10000 #endif + -/* Define __yy_memcpy. Note that the size argument - should be passed with type unsigned int, because that is what the non-GCC - definitions require. With GCC, __builtin_memcpy takes an arg - of type size_t, but it can handle unsigned int. */ - -#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#else /* not GNU C or C++ */ -#ifndef __cplusplus -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (to, from, count) - char *to; - char *from; - unsigned int count; +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif { - register char *f = from; - register char *t = to; - register int i = count; + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; - while (i-- > 0) - *t++ = *f++; + return yyd - 1; } +# endif +# endif + +#endif /* !YYERROR_VERBOSE */ + + -#else /* __cplusplus */ +#if YYDEBUG +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ +#if defined (__STDC__) || defined (__cplusplus) +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +#else static void -__yy_memcpy (char *to, char *from, unsigned int count) +yysymprint (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE *yyvaluep; +#endif { - register char *t = to; - register char *f = from; - register int i = count; + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; - while (i-- > 0) - *t++ = *f++; + if (yytype < YYNTOKENS) + { + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +# ifdef YYPRINT + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + } + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); } +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yytype, yyvaluep) + int yytype; + YYSTYPE *yyvaluep; #endif -#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + switch (yytype) + { + + default: + break; + } +} -#line 217 "/usr/share/bison.simple" -/* The user can define YYPARSE_PARAM as the name of an argument to be passed - into yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ +/* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM -#ifdef __cplusplus -#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM -#define YYPARSE_PARAM_DECL -#else /* not __cplusplus */ -#define YYPARSE_PARAM_ARG YYPARSE_PARAM -#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -#endif /* not __cplusplus */ -#else /* not YYPARSE_PARAM */ -#define YYPARSE_PARAM_ARG -#define YYPARSE_PARAM_DECL -#endif /* not YYPARSE_PARAM */ +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM); +# else +int yyparse (); +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ -/* Prevent warning if -Wstrict-prototypes. */ -#ifdef __GNUC__ #ifdef YYPARSE_PARAM -int yyparse (void *); +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM) +# else +int yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +yyparse (void) #else -int yyparse (void); +int +yyparse () + #endif #endif - -int -yyparse(YYPARSE_PARAM_ARG) - YYPARSE_PARAM_DECL { + register int yystate; register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + short yyssa[YYINITDEPTH]; + short *yyss = yyssa; register short *yyssp; - register YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1 = 0; /* lookahead token as an internal (translated) token number */ - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ -#ifdef YYLSP_NEEDED - YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; -#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else #define YYPOPSTACK (yyvsp--, yyssp--) -#endif - int yystacksize = YYINITDEPTH; - int yyfree_stacks = 0; + YYSIZE_T yystacksize = YYINITDEPTH; -#ifdef YYPURE - int yychar; - YYSTYPE yylval; - int yynerrs; -#ifdef YYLSP_NEEDED - YYLTYPE yylloc; -#endif -#endif + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ int yylen; -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Starting parse\n"); -#endif + YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; @@ -1997,110 +2552,96 @@ so that they stay on the same level as the state stack. The wasted elements are never initialized. */ - yyssp = yyss - 1; + yyssp = yyss; yyvsp = yyvs; -#ifdef YYLSP_NEEDED - yylsp = yyls; -#endif -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Give user a chance to reallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; -#ifdef YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; -#endif + goto yysetstate; +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; + YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow - /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ -#ifdef YYLSP_NEEDED - /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yyls1, size * sizeof (*yylsp), - &yystacksize); -#else - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yystacksize); -#endif + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), - yyss = yyss1; yyvs = yyvs1; -#ifdef YYLSP_NEEDED - yyls = yyls1; -#endif + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } #else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - { - yyerror("parser stack overflow"); - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 2; - } + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) + if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; -#ifndef YYSTACK_USE_ALLOCA - yyfree_stacks = 1; -#endif - yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); - __yy_memcpy ((char *)yyss, (char *)yyss1, - size * (unsigned int) sizeof (*yyssp)); - yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); - __yy_memcpy ((char *)yyvs, (char *)yyvs1, - size * (unsigned int) sizeof (*yyvsp)); -#ifdef YYLSP_NEEDED - yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); - __yy_memcpy ((char *)yyls, (char *)yyls1, - size * (unsigned int) sizeof (*yylsp)); -#endif + + { + short *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif #endif /* no yyoverflow */ - yyssp = yyss + size - 1; - yyvsp = yyvs + size - 1; -#ifdef YYLSP_NEEDED - yylsp = yyls + size - 1; -#endif + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yystacksize); -#endif - if (yyssp >= yyss + yystacksize - 1) + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) YYABORT; } -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); -#endif + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; - yybackup: + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: /* Do appropriate processing given the current state. */ /* Read a lookahead token if we need one and don't already have one. */ @@ -2109,254 +2650,314 @@ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; - if (yyn == YYFLAG) + if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Reading a token: "); -#endif + YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ + if (yychar <= YYEOF) { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Now at end of input.\n"); -#endif + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); } else { - yychar1 = YYTRANSLATE(yychar); - -#if YYDEBUG != 0 - if (yydebug) - { - fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise meaning - of a token, for further debugging info. */ -#ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -#endif - fprintf (stderr, ")\n"); - } -#endif + yytoken = YYTRANSLATE (yychar); + YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); } - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) + if (yyn <= 0) { - if (yyn == YYFLAG) + if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } - else if (yyn == 0) - goto yyerrlab; if (yyn == YYFINAL) YYACCEPT; /* Shift the lookahead token. */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); -#endif + YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); /* Discard the token being shifted unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; yystate = yyn; goto yynewstate; -/* Do the default action for the current state. */ -yydefault: +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; + goto yyreduce; -/* Do a reduction. yyn is the number of a rule to reduce with. */ + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ yyreduce: + /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; - if (yylen > 0) - yyval = yyvsp[1-yylen]; /* implement default value of the action */ - -#if YYDEBUG != 0 - if (yydebug) - { - int i; - - fprintf (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - /* Print the symbols being reduced, and their result. */ - for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) - fprintf (stderr, "%s ", yytname[yyrhs[i]]); - fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; - switch (yyn) { -case 2: -#line 987 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 3: +#line 993 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (yyvsp[0].UIntVal > (uint32_t)INT32_MAX) // Outside of my range! ThrowException("Value too large for type!"); yyval.SIntVal = (int32_t)yyvsp[0].UIntVal; -; - break;} -case 4: -#line 995 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ +;} + break; + + case 5: +#line 1001 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (yyvsp[0].UInt64Val > (uint64_t)INT64_MAX) // Outside of my range! ThrowException("Value too large for type!"); yyval.SInt64Val = (int64_t)yyvsp[0].UInt64Val; -; - break;} -case 39: -#line 1019 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ +;} + break; + + case 40: +#line 1025 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.StrVal = yyvsp[-1].StrVal; - ; - break;} -case 40: -#line 1022 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 41: +#line 1028 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.StrVal = 0; - ; - break;} -case 41: -#line 1026 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ yyval.Linkage = GlobalValue::InternalLinkage; ; - break;} -case 42: -#line 1027 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ yyval.Linkage = GlobalValue::LinkOnceLinkage; ; - break;} -case 43: -#line 1028 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ yyval.Linkage = GlobalValue::WeakLinkage; ; - break;} -case 44: -#line 1029 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ yyval.Linkage = GlobalValue::AppendingLinkage; ; - break;} -case 45: -#line 1030 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ yyval.Linkage = GlobalValue::ExternalLinkage; ; - break;} -case 46: -#line 1032 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ yyval.UIntVal = CallingConv::C; ; - break;} -case 47: -#line 1033 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ yyval.UIntVal = CallingConv::C; ; - break;} -case 48: -#line 1034 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ yyval.UIntVal = CallingConv::Fast; ; - break;} -case 49: -#line 1035 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ yyval.UIntVal = CallingConv::Cold; ; - break;} -case 50: -#line 1036 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ - if ((unsigned)yyvsp[0].UInt64Val != yyvsp[0].UInt64Val) - ThrowException("Calling conv too large!"); - yyval.UIntVal = yyvsp[0].UInt64Val; - ; - break;} -case 52: -#line 1049 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ yyval.TypeVal = new PATypeHolder(yyvsp[0].PrimType); ; - break;} -case 54: -#line 1050 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ yyval.TypeVal = new PATypeHolder(yyvsp[0].PrimType); ; - break;} -case 55: -#line 1052 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ - if (!UpRefs.empty()) - ThrowException("Invalid upreference in type: " + (*yyvsp[0].TypeVal)->getDescription()); - yyval.TypeVal = yyvsp[0].TypeVal; - ; - break;} -case 69: -#line 1063 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ - yyval.TypeVal = new PATypeHolder(OpaqueType::get()); - ; - break;} -case 70: -#line 1066 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ - yyval.TypeVal = new PATypeHolder(yyvsp[0].PrimType); - ; - break;} -case 71: -#line 1069 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Named types are also simple types... - yyval.TypeVal = new PATypeHolder(getTypeVal(yyvsp[0].ValIDVal)); -; - break;} -case 72: -#line 1075 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Type UpReference - if (yyvsp[0].UInt64Val > (uint64_t)~0U) ThrowException("Value out of range!"); - OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder - UpRefs.push_back(UpRefRecord((unsigned)yyvsp[0].UInt64Val, OT)); // Add to vector... - yyval.TypeVal = new PATypeHolder(OT); - UR_OUT("New Upreference!\n"); - ; - break;} -case 73: -#line 1082 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Function derived type? - std::vector Params; - for (std::list::iterator I = yyvsp[-1].TypeList->begin(), - E = yyvsp[-1].TypeList->end(); I != E; ++I) + ;} + break; + + case 42: +#line 1032 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.Linkage = GlobalValue::InternalLinkage; ;} + break; + + case 43: +#line 1033 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.Linkage = GlobalValue::LinkOnceLinkage; ;} + break; + + case 44: +#line 1034 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.Linkage = GlobalValue::WeakLinkage; ;} + break; + + case 45: +#line 1035 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.Linkage = GlobalValue::AppendingLinkage; ;} + break; + + case 46: +#line 1036 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.Linkage = GlobalValue::ExternalLinkage; ;} + break; + + case 47: +#line 1038 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.UIntVal = CallingConv::C; ;} + break; + + case 48: +#line 1039 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.UIntVal = CallingConv::C; ;} + break; + + case 49: +#line 1040 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.UIntVal = CallingConv::Fast; ;} + break; + + case 50: +#line 1041 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.UIntVal = CallingConv::Cold; ;} + break; + + case 51: +#line 1042 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + if ((unsigned)yyvsp[0].UInt64Val != yyvsp[0].UInt64Val) + ThrowException("Calling conv too large!"); + yyval.UIntVal = yyvsp[0].UInt64Val; + ;} + break; + + case 52: +#line 1050 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.UIntVal = 0; ;} + break; + + case 53: +#line 1051 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + yyval.UIntVal = yyvsp[0].UInt64Val; + if (yyval.UIntVal != 0 && !isPowerOf2_32(yyval.UIntVal)) + ThrowException("Alignment must be a power of two!"); +;} + break; + + case 54: +#line 1056 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.UIntVal = 0; ;} + break; + + case 55: +#line 1057 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + yyval.UIntVal = yyvsp[0].UInt64Val; + if (yyval.UIntVal != 0 && !isPowerOf2_32(yyval.UIntVal)) + ThrowException("Alignment must be a power of two!"); +;} + break; + + case 56: +#line 1064 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + for (unsigned i = 0, e = strlen(yyvsp[0].StrVal); i != e; ++i) + if (yyvsp[0].StrVal[i] == '"' || yyvsp[0].StrVal[i] == '\\') + ThrowException("Invalid character in section name!"); + yyval.StrVal = yyvsp[0].StrVal; +;} + break; + + case 57: +#line 1071 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.StrVal = 0; ;} + break; + + case 58: +#line 1072 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.StrVal = yyvsp[0].StrVal; ;} + break; + + case 59: +#line 1077 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + {;} + break; + + case 60: +#line 1078 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + {;} + break; + + case 61: +#line 1079 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + CurGV->setSection(yyvsp[0].StrVal); + free(yyvsp[0].StrVal); + ;} + break; + + case 62: +#line 1083 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + if (yyvsp[0].UInt64Val != 0 && !isPowerOf2_32(yyvsp[0].UInt64Val)) + ThrowException("Alignment must be a power of two!"); + CurGV->setAlignment(yyvsp[0].UInt64Val); + ;} + break; + + case 64: +#line 1096 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.TypeVal = new PATypeHolder(yyvsp[0].PrimType); ;} + break; + + case 66: +#line 1097 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.TypeVal = new PATypeHolder(yyvsp[0].PrimType); ;} + break; + + case 67: +#line 1099 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + if (!UpRefs.empty()) + ThrowException("Invalid upreference in type: " + (*yyvsp[0].TypeVal)->getDescription()); + yyval.TypeVal = yyvsp[0].TypeVal; + ;} + break; + + case 81: +#line 1110 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + yyval.TypeVal = new PATypeHolder(OpaqueType::get()); + ;} + break; + + case 82: +#line 1113 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + yyval.TypeVal = new PATypeHolder(yyvsp[0].PrimType); + ;} + break; + + case 83: +#line 1116 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Named types are also simple types... + yyval.TypeVal = new PATypeHolder(getTypeVal(yyvsp[0].ValIDVal)); +;} + break; + + case 84: +#line 1122 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Type UpReference + if (yyvsp[0].UInt64Val > (uint64_t)~0U) ThrowException("Value out of range!"); + OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder + UpRefs.push_back(UpRefRecord((unsigned)yyvsp[0].UInt64Val, OT)); // Add to vector... + yyval.TypeVal = new PATypeHolder(OT); + UR_OUT("New Upreference!\n"); + ;} + break; + + case 85: +#line 1129 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Function derived type? + std::vector Params; + for (std::list::iterator I = yyvsp[-1].TypeList->begin(), + E = yyvsp[-1].TypeList->end(); I != E; ++I) Params.push_back(*I); bool isVarArg = Params.size() && Params.back() == Type::VoidTy; if (isVarArg) Params.pop_back(); @@ -2364,25 +2965,28 @@ yyval.TypeVal = new PATypeHolder(HandleUpRefs(FunctionType::get(*yyvsp[-3].TypeVal,Params,isVarArg))); delete yyvsp[-1].TypeList; // Delete the argument list delete yyvsp[-3].TypeVal; // Delete the return type handle - ; - break;} -case 74: -#line 1094 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Sized array type? + ;} + break; + + case 86: +#line 1141 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Sized array type? yyval.TypeVal = new PATypeHolder(HandleUpRefs(ArrayType::get(*yyvsp[-1].TypeVal, (unsigned)yyvsp[-3].UInt64Val))); delete yyvsp[-1].TypeVal; - ; - break;} -case 75: -#line 1099 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Vector type? + ;} + break; + + case 87: +#line 1145 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Vector type? yyval.TypeVal = new PATypeHolder(HandleUpRefs(VectorType::get(*yyvsp[-1].TypeVal))); delete yyvsp[-1].TypeVal; - ; - break;} -case 76: -#line 1104 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // FixedVector type? + ;} + break; + + case 88: +#line 1150 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // FixedVector type? const llvm::Type* ElemTy = yyvsp[-1].TypeVal->get(); if ((unsigned)yyvsp[-2].UInt64Val != yyvsp[-2].UInt64Val) { ThrowException("Unsigned result not equal to signed result"); @@ -2390,13 +2994,16 @@ if(!ElemTy->isPrimitiveType()) { ThrowException("Element type of a FixedVectorType must be primitive"); } + //if (!isPowerOf2_32($2)) + // ThrowException("Vector length should be a power of 2!"); yyval.TypeVal = new PATypeHolder(HandleUpRefs(FixedVectorType::get(*yyvsp[-1].TypeVal, (unsigned)yyvsp[-2].UInt64Val))); delete yyvsp[-1].TypeVal; - ; - break;} -case 77: -#line 1116 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Structure type? + ;} + break; + + case 89: +#line 1164 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Structure type? std::vector Elements; for (std::list::iterator I = yyvsp[-1].TypeList->begin(), E = yyvsp[-1].TypeList->end(); I != E; ++I) @@ -2404,55 +3011,63 @@ yyval.TypeVal = new PATypeHolder(HandleUpRefs(StructType::get(Elements))); delete yyvsp[-1].TypeList; - ; - break;} -case 78: -#line 1125 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Empty structure type? + ;} + break; + + case 90: +#line 1173 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Empty structure type? yyval.TypeVal = new PATypeHolder(StructType::get(std::vector())); - ; - break;} -case 79: -#line 1128 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Pointer type? + ;} + break; + + case 91: +#line 1176 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Pointer type? yyval.TypeVal = new PATypeHolder(HandleUpRefs(PointerType::get(*yyvsp[-1].TypeVal))); delete yyvsp[-1].TypeVal; - ; - break;} -case 80: -#line 1136 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 92: +#line 1184 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.TypeList = new std::list(); yyval.TypeList->push_back(*yyvsp[0].TypeVal); delete yyvsp[0].TypeVal; - ; - break;} -case 81: -#line 1140 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 93: +#line 1188 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { (yyval.TypeList=yyvsp[-2].TypeList)->push_back(*yyvsp[0].TypeVal); delete yyvsp[0].TypeVal; - ; - break;} -case 83: -#line 1146 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 95: +#line 1194 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { (yyval.TypeList=yyvsp[-2].TypeList)->push_back(Type::VoidTy); - ; - break;} -case 84: -#line 1149 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 96: +#line 1197 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { (yyval.TypeList = new std::list())->push_back(Type::VoidTy); - ; - break;} -case 85: -#line 1152 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 97: +#line 1200 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.TypeList = new std::list(); - ; - break;} -case 86: -#line 1162 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Nonempty unsized arr + ;} + break; + + case 98: +#line 1210 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Nonempty unsized arr const ArrayType *ATy = dyn_cast(yyvsp[-3].TypeVal->get()); if (ATy == 0) ThrowException("Cannot make array constant with type: '" + @@ -2476,11 +3091,12 @@ yyval.ConstVal = ConstantArray::get(ATy, *yyvsp[-1].ConstVector); delete yyvsp[-3].TypeVal; delete yyvsp[-1].ConstVector; - ; - break;} -case 87: -#line 1187 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 99: +#line 1235 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { const ArrayType *ATy = dyn_cast(yyvsp[-2].TypeVal->get()); if (ATy == 0) ThrowException("Cannot make array constant with type: '" + @@ -2492,11 +3108,12 @@ " arguments, but has size of " + itostr(NumElements) +"!"); yyval.ConstVal = ConstantArray::get(ATy, std::vector()); delete yyvsp[-2].TypeVal; - ; - break;} -case 88: -#line 1200 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 100: +#line 1248 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { const ArrayType *ATy = dyn_cast(yyvsp[-2].TypeVal->get()); if (ATy == 0) ThrowException("Cannot make array constant with type: '" + @@ -2523,11 +3140,12 @@ free(yyvsp[0].StrVal); yyval.ConstVal = ConstantArray::get(ATy, Vals); delete yyvsp[-2].TypeVal; - ; - break;} -case 89: -#line 1228 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Nonempty unsized arr + ;} + break; + + case 101: +#line 1276 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Nonempty unsized arr const FixedVectorType *PTy = dyn_cast(yyvsp[-3].TypeVal->get()); if (PTy == 0) ThrowException("Cannot make vector constant with type: '" + @@ -2551,11 +3169,12 @@ yyval.ConstVal = ConstantVector::get(PTy, *yyvsp[-1].ConstVector); delete yyvsp[-3].TypeVal; delete yyvsp[-1].ConstVector; - ; - break;} -case 90: -#line 1253 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 102: +#line 1301 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { const StructType *STy = dyn_cast(yyvsp[-3].TypeVal->get()); if (STy == 0) ThrowException("Cannot make struct constant with type: '" + @@ -2574,11 +3193,12 @@ yyval.ConstVal = ConstantStruct::get(STy, *yyvsp[-1].ConstVector); delete yyvsp[-3].TypeVal; delete yyvsp[-1].ConstVector; - ; - break;} -case 91: -#line 1273 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 103: +#line 1321 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { const StructType *STy = dyn_cast(yyvsp[-2].TypeVal->get()); if (STy == 0) ThrowException("Cannot make struct constant with type: '" + @@ -2589,11 +3209,12 @@ yyval.ConstVal = ConstantStruct::get(STy, std::vector()); delete yyvsp[-2].TypeVal; - ; - break;} -case 92: -#line 1285 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 104: +#line 1333 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { const PointerType *PTy = dyn_cast(yyvsp[-1].TypeVal->get()); if (PTy == 0) ThrowException("Cannot make null pointer constant with type: '" + @@ -2601,18 +3222,20 @@ yyval.ConstVal = ConstantPointerNull::get(PTy); delete yyvsp[-1].TypeVal; - ; - break;} -case 93: -#line 1294 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 105: +#line 1342 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ConstVal = UndefValue::get(yyvsp[-1].TypeVal->get()); delete yyvsp[-1].TypeVal; - ; - break;} -case 94: -#line 1298 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 106: +#line 1346 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { const PointerType *Ty = dyn_cast(yyvsp[-1].TypeVal->get()); if (Ty == 0) ThrowException("Global const reference must be a pointer type!"); @@ -2670,66 +3293,74 @@ yyval.ConstVal = cast(V); delete yyvsp[-1].TypeVal; // Free the type handle - ; - break;} -case 95: -#line 1357 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 107: +#line 1405 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (yyvsp[-1].TypeVal->get() != yyvsp[0].ConstVal->getType()) ThrowException("Mismatched types for constant expression!"); yyval.ConstVal = yyvsp[0].ConstVal; delete yyvsp[-1].TypeVal; - ; - break;} -case 96: -#line 1363 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 108: +#line 1411 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { const Type *Ty = yyvsp[-1].TypeVal->get(); if (isa(Ty) || Ty == Type::LabelTy || isa(Ty)) ThrowException("Cannot create a null initialized value of this type!"); yyval.ConstVal = Constant::getNullValue(Ty); delete yyvsp[-1].TypeVal; - ; - break;} -case 97: -#line 1371 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // integral constants + ;} + break; + + case 109: +#line 1419 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // integral constants if (!ConstantSInt::isValueValidForType(yyvsp[-1].PrimType, yyvsp[0].SInt64Val)) ThrowException("Constant value doesn't fit in type!"); yyval.ConstVal = ConstantSInt::get(yyvsp[-1].PrimType, yyvsp[0].SInt64Val); - ; - break;} -case 98: -#line 1376 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // integral constants + ;} + break; + + case 110: +#line 1424 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // integral constants if (!ConstantUInt::isValueValidForType(yyvsp[-1].PrimType, yyvsp[0].UInt64Val)) ThrowException("Constant value doesn't fit in type!"); yyval.ConstVal = ConstantUInt::get(yyvsp[-1].PrimType, yyvsp[0].UInt64Val); - ; - break;} -case 99: -#line 1381 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Boolean constants + ;} + break; + + case 111: +#line 1429 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Boolean constants yyval.ConstVal = ConstantBool::True; - ; - break;} -case 100: -#line 1384 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Boolean constants + ;} + break; + + case 112: +#line 1432 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Boolean constants yyval.ConstVal = ConstantBool::False; - ; - break;} -case 101: -#line 1387 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Float & Double constants + ;} + break; + + case 113: +#line 1435 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Float & Double constants if (!ConstantFP::isValueValidForType(yyvsp[-1].PrimType, yyvsp[0].FPVal)) ThrowException("Floating point constant invalid for type!!"); yyval.ConstVal = ConstantFP::get(yyvsp[-1].PrimType, yyvsp[0].FPVal); - ; - break;} -case 102: -#line 1394 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 114: +#line 1442 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (!yyvsp[-3].ConstVal->getType()->isFirstClassType()) ThrowException("cast constant expression from a non-primitive type: '" + yyvsp[-3].ConstVal->getType()->getDescription() + "'!"); @@ -2738,11 +3369,12 @@ yyvsp[-1].TypeVal->get()->getDescription() + "'!"); yyval.ConstVal = ConstantExpr::getCast(yyvsp[-3].ConstVal, yyvsp[-1].TypeVal->get()); delete yyvsp[-1].TypeVal; - ; - break;} -case 103: -#line 1404 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 115: +#line 1452 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (!isa(yyvsp[-2].ConstVal->getType())) ThrowException("GetElementPtr requires a pointer operand!"); @@ -2772,21 +3404,23 @@ delete yyvsp[-1].ValueList; yyval.ConstVal = ConstantExpr::getGetElementPtr(yyvsp[-2].ConstVal, IdxVec); - ; - break;} -case 104: -#line 1435 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 116: +#line 1483 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (yyvsp[-5].ConstVal->getType() != Type::BoolTy) ThrowException("Select condition must be of boolean type!"); if (yyvsp[-3].ConstVal->getType() != yyvsp[-1].ConstVal->getType()) ThrowException("Select operand types must match!"); yyval.ConstVal = ConstantExpr::getSelect(yyvsp[-5].ConstVal, yyvsp[-3].ConstVal, yyvsp[-1].ConstVal); - ; - break;} -case 105: -#line 1442 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 117: +#line 1490 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (yyvsp[-3].ConstVal->getType() != yyvsp[-1].ConstVal->getType()) ThrowException("Binary operator types must match!"); // HACK: llvm 1.3 and earlier used to emit invalid pointer constant exprs. @@ -2806,30 +3440,33 @@ ConstantExpr::getCast(yyvsp[-1].ConstVal, IntPtrTy)); yyval.ConstVal = ConstantExpr::getCast(yyval.ConstVal, yyvsp[-3].ConstVal->getType()); } - ; - break;} -case 106: -#line 1463 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 118: +#line 1511 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (yyvsp[-3].ConstVal->getType() != yyvsp[-1].ConstVal->getType()) ThrowException("Logical operator types must match!"); if (!yyvsp[-3].ConstVal->getType()->isIntegral() && !yyvsp[-3].ConstVal->getType()->isIntegralVector()) ThrowException("Logical operands must have integral types!"); yyval.ConstVal = ConstantExpr::get(yyvsp[-5].BinaryOpVal, yyvsp[-3].ConstVal, yyvsp[-1].ConstVal); - ; - break;} -case 107: -#line 1471 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 119: +#line 1519 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (yyvsp[-3].ConstVal->getType() != yyvsp[-1].ConstVal->getType()) ThrowException("setcc operand types must match!"); yyval.ConstVal = ConstantExpr::get(yyvsp[-5].BinaryOpVal, yyvsp[-3].ConstVal, yyvsp[-1].ConstVal); - ; - break;} -case 108: -#line 1476 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 120: +#line 1524 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (yyvsp[-1].ConstVal->getType() != Type::UByteTy) ThrowException("Shift count for shift constant must be unsigned byte!"); if (!yyvsp[-3].ConstVal->getType()->isInteger() && @@ -2837,58 +3474,67 @@ ThrowException("Shift constant expression requires integer operand!"); } yyval.ConstVal = ConstantExpr::get(yyvsp[-5].OtherOpVal, yyvsp[-3].ConstVal, yyvsp[-1].ConstVal); - ; - break;} -case 109: -#line 1488 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 121: +#line 1536 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { (yyval.ConstVector = yyvsp[-2].ConstVector)->push_back(yyvsp[0].ConstVal); - ; - break;} -case 110: -#line 1491 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 122: +#line 1539 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ConstVector = new std::vector(); yyval.ConstVector->push_back(yyvsp[0].ConstVal); - ; - break;} -case 111: -#line 1498 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ yyval.BoolVal = false; ; - break;} -case 112: -#line 1498 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ yyval.BoolVal = true; ; - break;} -case 113: -#line 1508 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 123: +#line 1546 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.BoolVal = false; ;} + break; + + case 124: +#line 1546 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.BoolVal = true; ;} + break; + + case 125: +#line 1556 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ModuleVal = ParserResult = yyvsp[0].ModuleVal; CurModule.ModuleDone(); -; - break;} -case 114: -#line 1515 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ +;} + break; + + case 126: +#line 1563 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ModuleVal = yyvsp[-1].ModuleVal; CurFun.FunctionDone(); - ; - break;} -case 115: -#line 1519 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 127: +#line 1567 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ModuleVal = yyvsp[-1].ModuleVal; - ; - break;} -case 116: -#line 1522 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 128: +#line 1570 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ModuleVal = yyvsp[-1].ModuleVal; - ; - break;} -case 117: -#line 1525 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 129: +#line 1573 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ModuleVal = CurModule.CurrentModule; // Emit an error if there are any unresolved types left. if (!CurModule.LateResolveTypes.empty()) { @@ -2898,11 +3544,12 @@ else ThrowException("Reference to an undefined type: #" + itostr(DID.Num)); } - ; - break;} -case 118: -#line 1538 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 130: +#line 1586 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Eagerly resolve types. This is not an optimization, this is a // requirement that is due to the fact that we could have this: // @@ -2921,171 +3568,209 @@ } delete yyvsp[0].TypeVal; - ; - break;} -case 119: -#line 1558 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Function prototypes can be in const pool - ; - break;} -case 120: -#line 1560 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 131: +#line 1606 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Function prototypes can be in const pool + ;} + break; + + case 132: +#line 1608 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (yyvsp[0].ConstVal == 0) ThrowException("Global value initializer is not a constant!"); - ParseGlobalVariable(yyvsp[-3].StrVal, yyvsp[-2].Linkage, yyvsp[-1].BoolVal, yyvsp[0].ConstVal->getType(), yyvsp[0].ConstVal); - ; - break;} -case 121: -#line 1564 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ - ParseGlobalVariable(yyvsp[-3].StrVal, GlobalValue::ExternalLinkage, yyvsp[-1].BoolVal, *yyvsp[0].TypeVal, 0); + CurGV = ParseGlobalVariable(yyvsp[-3].StrVal, yyvsp[-2].Linkage, yyvsp[-1].BoolVal, yyvsp[0].ConstVal->getType(), yyvsp[0].ConstVal); + ;} + break; + + case 133: +#line 1611 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + CurGV = 0; + ;} + break; + + case 134: +#line 1614 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + CurGV = ParseGlobalVariable(yyvsp[-3].StrVal, GlobalValue::ExternalLinkage, + yyvsp[-1].BoolVal, *yyvsp[0].TypeVal, 0); delete yyvsp[0].TypeVal; - ; - break;} -case 122: -#line 1568 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ - ; - break;} -case 123: -#line 1570 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ - ; - break;} -case 124: -#line 1572 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ - ; - break;} -case 125: -#line 1577 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ yyval.Endianness = Module::BigEndian; ; - break;} -case 126: -#line 1578 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ yyval.Endianness = Module::LittleEndian; ; - break;} -case 127: -#line 1580 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 135: +#line 1618 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + CurGV = 0; + ;} + break; + + case 136: +#line 1621 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + ;} + break; + + case 137: +#line 1623 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + ;} + break; + + case 138: +#line 1625 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + ;} + break; + + case 139: +#line 1630 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.Endianness = Module::BigEndian; ;} + break; + + case 140: +#line 1631 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.Endianness = Module::LittleEndian; ;} + break; + + case 141: +#line 1633 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { CurModule.CurrentModule->setEndianness(yyvsp[0].Endianness); - ; - break;} -case 128: -#line 1583 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 142: +#line 1636 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (yyvsp[0].UInt64Val == 32) CurModule.CurrentModule->setPointerSize(Module::Pointer32); else if (yyvsp[0].UInt64Val == 64) CurModule.CurrentModule->setPointerSize(Module::Pointer64); else ThrowException("Invalid pointer size: '" + utostr(yyvsp[0].UInt64Val) + "'!"); - ; - break;} -case 129: -#line 1591 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 143: +#line 1644 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { CurModule.CurrentModule->setTargetTriple(yyvsp[0].StrVal); free(yyvsp[0].StrVal); - ; - break;} -case 131: -#line 1598 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 145: +#line 1651 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { CurModule.CurrentModule->addLibrary(yyvsp[0].StrVal); free(yyvsp[0].StrVal); - ; - break;} -case 132: -#line 1602 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 146: +#line 1655 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { CurModule.CurrentModule->addLibrary(yyvsp[0].StrVal); free(yyvsp[0].StrVal); - ; - break;} -case 133: -#line 1606 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ - ; - break;} -case 137: -#line 1615 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ yyval.StrVal = 0; ; - break;} -case 138: -#line 1617 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 147: +#line 1659 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + ;} + break; + + case 151: +#line 1668 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.StrVal = 0; ;} + break; + + case 152: +#line 1670 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (*yyvsp[-1].TypeVal == Type::VoidTy) ThrowException("void typed arguments are invalid!"); yyval.ArgVal = new std::pair(yyvsp[-1].TypeVal, yyvsp[0].StrVal); -; - break;} -case 139: -#line 1623 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ +;} + break; + + case 153: +#line 1676 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ArgList = yyvsp[-2].ArgList; yyvsp[-2].ArgList->push_back(*yyvsp[0].ArgVal); delete yyvsp[0].ArgVal; - ; - break;} -case 140: -#line 1628 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 154: +#line 1681 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ArgList = new std::vector >(); yyval.ArgList->push_back(*yyvsp[0].ArgVal); delete yyvsp[0].ArgVal; - ; - break;} -case 141: -#line 1634 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 155: +#line 1687 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ArgList = yyvsp[0].ArgList; - ; - break;} -case 142: -#line 1637 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 156: +#line 1690 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ArgList = yyvsp[-2].ArgList; yyval.ArgList->push_back(std::pair(new PATypeHolder(Type::VoidTy), 0)); - ; - break;} -case 143: -#line 1642 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 157: +#line 1695 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ArgList = new std::vector >(); yyval.ArgList->push_back(std::make_pair(new PATypeHolder(Type::VoidTy), (char*)0)); - ; - break;} -case 144: -#line 1646 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 158: +#line 1699 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ArgList = 0; - ; - break;} -case 145: -#line 1650 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ - UnEscapeLexed(yyvsp[-3].StrVal); - std::string FunctionName(yyvsp[-3].StrVal); - free(yyvsp[-3].StrVal); // Free strdup'd memory! + ;} + break; + + case 159: +#line 1704 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + UnEscapeLexed(yyvsp[-5].StrVal); + std::string FunctionName(yyvsp[-5].StrVal); + free(yyvsp[-5].StrVal); // Free strdup'd memory! - if (!(*yyvsp[-4].TypeVal)->isFirstClassType() && *yyvsp[-4].TypeVal != Type::VoidTy) + if (!(*yyvsp[-6].TypeVal)->isFirstClassType() && *yyvsp[-6].TypeVal != Type::VoidTy) ThrowException("LLVM functions cannot return aggregate types!"); std::vector ParamTypeList; - if (yyvsp[-1].ArgList) { // If there are arguments... - for (std::vector >::iterator I = yyvsp[-1].ArgList->begin(); - I != yyvsp[-1].ArgList->end(); ++I) + if (yyvsp[-3].ArgList) { // If there are arguments... + for (std::vector >::iterator I = yyvsp[-3].ArgList->begin(); + I != yyvsp[-3].ArgList->end(); ++I) ParamTypeList.push_back(I->first->get()); } bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy; if (isVarArg) ParamTypeList.pop_back(); - const FunctionType *FT = FunctionType::get(*yyvsp[-4].TypeVal, ParamTypeList, isVarArg); + const FunctionType *FT = FunctionType::get(*yyvsp[-6].TypeVal, ParamTypeList, isVarArg); const PointerType *PFT = PointerType::get(FT); - delete yyvsp[-4].TypeVal; + delete yyvsp[-6].TypeVal; ValID ID; if (!FunctionName.empty()) { @@ -3122,101 +3807,118 @@ } CurFun.FunctionStart(Fn); - Fn->setCallingConv(yyvsp[-5].UIntVal); + Fn->setCallingConv(yyvsp[-7].UIntVal); + Fn->setAlignment(yyvsp[0].UIntVal); + if (yyvsp[-1].StrVal) { + Fn->setSection(yyvsp[-1].StrVal); + free(yyvsp[-1].StrVal); + } // Add all of the arguments we parsed to the function... - if (yyvsp[-1].ArgList) { // Is null if empty... + if (yyvsp[-3].ArgList) { // Is null if empty... if (isVarArg) { // Nuke the last entry - assert(yyvsp[-1].ArgList->back().first->get() == Type::VoidTy && yyvsp[-1].ArgList->back().second == 0&& + assert(yyvsp[-3].ArgList->back().first->get() == Type::VoidTy && yyvsp[-3].ArgList->back().second == 0&& "Not a varargs marker!"); - delete yyvsp[-1].ArgList->back().first; - yyvsp[-1].ArgList->pop_back(); // Delete the last entry + delete yyvsp[-3].ArgList->back().first; + yyvsp[-3].ArgList->pop_back(); // Delete the last entry } Function::arg_iterator ArgIt = Fn->arg_begin(); - for (std::vector >::iterator I = yyvsp[-1].ArgList->begin(); - I != yyvsp[-1].ArgList->end(); ++I, ++ArgIt) { + for (std::vector >::iterator I = yyvsp[-3].ArgList->begin(); + I != yyvsp[-3].ArgList->end(); ++I, ++ArgIt) { delete I->first; // Delete the typeholder... setValueName(ArgIt, I->second); // Insert arg into symtab... InsertValue(ArgIt); } - delete yyvsp[-1].ArgList; // We're now done with the argument list + delete yyvsp[-3].ArgList; // We're now done with the argument list } -; - break;} -case 148: -#line 1732 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ +;} + break; + + case 162: +#line 1791 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.FunctionVal = CurFun.CurrentFunction; // Make sure that we keep track of the linkage type even if there was a // previous "declare". yyval.FunctionVal->setLinkage(yyvsp[-2].Linkage); -; - break;} -case 151: -#line 1742 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ +;} + break; + + case 165: +#line 1801 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.FunctionVal = yyvsp[-1].FunctionVal; -; - break;} -case 152: -#line 1746 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ CurFun.isDeclare = true; ; - break;} -case 153: -#line 1746 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ +;} + break; + + case 166: +#line 1805 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { CurFun.isDeclare = true; ;} + break; + + case 167: +#line 1805 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.FunctionVal = CurFun.CurrentFunction; CurFun.FunctionDone(); -; - break;} -case 154: -#line 1755 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // A reference to a direct constant +;} + break; + + case 168: +#line 1814 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // A reference to a direct constant yyval.ValIDVal = ValID::create(yyvsp[0].SInt64Val); - ; - break;} -case 155: -#line 1758 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 169: +#line 1817 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ValIDVal = ValID::create(yyvsp[0].UInt64Val); - ; - break;} -case 156: -#line 1761 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Perhaps it's an FP constant? + ;} + break; + + case 170: +#line 1820 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Perhaps it's an FP constant? yyval.ValIDVal = ValID::create(yyvsp[0].FPVal); - ; - break;} -case 157: -#line 1764 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 171: +#line 1823 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ValIDVal = ValID::create(ConstantBool::True); - ; - break;} -case 158: -#line 1767 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 172: +#line 1826 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ValIDVal = ValID::create(ConstantBool::False); - ; - break;} -case 159: -#line 1770 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 173: +#line 1829 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ValIDVal = ValID::createNull(); - ; - break;} -case 160: -#line 1773 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 174: +#line 1832 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ValIDVal = ValID::createUndef(); - ; - break;} -case 161: -#line 1776 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Nonempty unsized vector + ;} + break; + + case 175: +#line 1835 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Nonempty unsized vector const Type *ETy = (*yyvsp[-1].ConstVector)[0]->getType(); int NumElements = yyvsp[-1].ConstVector->size(); @@ -3239,65 +3941,74 @@ yyval.ValIDVal = ValID::create(ConstantVector::get(pt, *yyvsp[-1].ConstVector)); delete PTy; delete yyvsp[-1].ConstVector; - ; - break;} -case 162: -#line 1800 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 176: +#line 1859 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ValIDVal = ValID::create(yyvsp[0].ConstVal); - ; - break;} -case 163: -#line 1807 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Is it an integer reference...? + ;} + break; + + case 177: +#line 1866 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Is it an integer reference...? yyval.ValIDVal = ValID::create(yyvsp[0].SIntVal); - ; - break;} -case 164: -#line 1810 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Is it a named reference...? + ;} + break; + + case 178: +#line 1869 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Is it a named reference...? yyval.ValIDVal = ValID::create(yyvsp[0].StrVal); - ; - break;} -case 167: -#line 1821 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 181: +#line 1880 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ValueVal = getVal(*yyvsp[-1].TypeVal, yyvsp[0].ValIDVal); delete yyvsp[-1].TypeVal; - ; - break;} -case 168: -#line 1825 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 182: +#line 1884 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.FunctionVal = yyvsp[-1].FunctionVal; - ; - break;} -case 169: -#line 1828 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Do not allow functions with 0 basic blocks + ;} + break; + + case 183: +#line 1887 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Do not allow functions with 0 basic blocks yyval.FunctionVal = yyvsp[-1].FunctionVal; - ; - break;} -case 170: -#line 1836 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 184: +#line 1895 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { setValueName(yyvsp[0].TermInstVal, yyvsp[-1].StrVal); InsertValue(yyvsp[0].TermInstVal); yyvsp[-2].BasicBlockVal->getInstList().push_back(yyvsp[0].TermInstVal); InsertValue(yyvsp[-2].BasicBlockVal); yyval.BasicBlockVal = yyvsp[-2].BasicBlockVal; - ; - break;} -case 171: -#line 1845 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 185: +#line 1904 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyvsp[-1].BasicBlockVal->getInstList().push_back(yyvsp[0].InstVal); yyval.BasicBlockVal = yyvsp[-1].BasicBlockVal; - ; - break;} -case 172: -#line 1849 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 186: +#line 1908 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.BasicBlockVal = CurBB = getBBVal(ValID::create((int)CurFun.NextBBNum++), true); // Make sure to move the basic block to the correct location in the @@ -3306,11 +4017,12 @@ Function::BasicBlockListType &BBL = CurFun.CurrentFunction->getBasicBlockList(); BBL.splice(BBL.end(), BBL, yyval.BasicBlockVal); - ; - break;} -case 173: -#line 1859 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 187: +#line 1918 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.BasicBlockVal = CurBB = getBBVal(ValID::create(yyvsp[0].StrVal), true); // Make sure to move the basic block to the correct location in the @@ -3319,35 +4031,40 @@ Function::BasicBlockListType &BBL = CurFun.CurrentFunction->getBasicBlockList(); BBL.splice(BBL.end(), BBL, yyval.BasicBlockVal); - ; - break;} -case 174: -#line 1870 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Return with a result... + ;} + break; + + case 188: +#line 1929 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Return with a result... yyval.TermInstVal = new ReturnInst(yyvsp[0].ValueVal); - ; - break;} -case 175: -#line 1873 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Return with no result... + ;} + break; + + case 189: +#line 1932 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Return with no result... yyval.TermInstVal = new ReturnInst(); - ; - break;} -case 176: -#line 1876 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Unconditional Branch... + ;} + break; + + case 190: +#line 1935 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Unconditional Branch... yyval.TermInstVal = new BranchInst(getBBVal(yyvsp[0].ValIDVal)); - ; - break;} -case 177: -#line 1879 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 191: +#line 1938 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.TermInstVal = new BranchInst(getBBVal(yyvsp[-3].ValIDVal), getBBVal(yyvsp[0].ValIDVal), getVal(Type::BoolTy, yyvsp[-6].ValIDVal)); - ; - break;} -case 178: -#line 1882 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 192: +#line 1941 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { SwitchInst *S = new SwitchInst(getVal(yyvsp[-7].PrimType, yyvsp[-6].ValIDVal), getBBVal(yyvsp[-3].ValIDVal), yyvsp[-1].JumpTable->size()); yyval.TermInstVal = S; @@ -3360,18 +4077,20 @@ ThrowException("Switch case is constant, but not a simple integer!"); } delete yyvsp[-1].JumpTable; - ; - break;} -case 179: -#line 1896 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 193: +#line 1955 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { SwitchInst *S = new SwitchInst(getVal(yyvsp[-6].PrimType, yyvsp[-5].ValIDVal), getBBVal(yyvsp[-2].ValIDVal), 0); yyval.TermInstVal = S; - ; - break;} -case 180: -#line 1901 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 194: +#line 1960 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { const PointerType *PFTy; const FunctionType *Ty; @@ -3422,34 +4141,38 @@ delete yyvsp[-10].TypeVal; delete yyvsp[-7].ValueList; - ; - break;} -case 181: -#line 1953 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 195: +#line 2012 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.TermInstVal = new UnwindInst(); - ; - break;} -case 182: -#line 1956 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 196: +#line 2015 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.TermInstVal = new UnreachableInst(); - ; - break;} -case 183: -#line 1962 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 197: +#line 2021 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.JumpTable = yyvsp[-5].JumpTable; Constant *V = cast(getValNonImprovising(yyvsp[-4].PrimType, yyvsp[-3].ValIDVal)); if (V == 0) ThrowException("May only switch on a constant pool value!"); yyval.JumpTable->push_back(std::make_pair(V, getBBVal(yyvsp[0].ValIDVal))); - ; - break;} -case 184: -#line 1970 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 198: +#line 2029 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.JumpTable = new std::vector >(); Constant *V = cast(getValNonImprovising(yyvsp[-4].PrimType, yyvsp[-3].ValIDVal)); @@ -3457,66 +4180,75 @@ ThrowException("May only switch on a constant pool value!"); yyval.JumpTable->push_back(std::make_pair(V, getBBVal(yyvsp[0].ValIDVal))); - ; - break;} -case 185: -#line 1980 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 199: +#line 2039 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Is this definition named?? if so, assign the name... setValueName(yyvsp[0].InstVal, yyvsp[-1].StrVal); InsertValue(yyvsp[0].InstVal); yyval.InstVal = yyvsp[0].InstVal; -; - break;} -case 186: -#line 1987 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Used for PHI nodes +;} + break; + + case 200: +#line 2046 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Used for PHI nodes yyval.PHIList = new std::list >(); yyval.PHIList->push_back(std::make_pair(getVal(*yyvsp[-5].TypeVal, yyvsp[-3].ValIDVal), getBBVal(yyvsp[-1].ValIDVal))); delete yyvsp[-5].TypeVal; - ; - break;} -case 187: -#line 1992 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 201: +#line 2051 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.PHIList = yyvsp[-6].PHIList; yyvsp[-6].PHIList->push_back(std::make_pair(getVal(yyvsp[-6].PHIList->front().first->getType(), yyvsp[-3].ValIDVal), getBBVal(yyvsp[-1].ValIDVal))); - ; - break;} -case 188: -#line 1998 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ // Used for call statements, and memory insts... + ;} + break; + + case 202: +#line 2057 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { // Used for call statements, and memory insts... yyval.ValueList = new std::vector(); yyval.ValueList->push_back(yyvsp[0].ValueVal); - ; - break;} -case 189: -#line 2002 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 203: +#line 2061 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ValueList = yyvsp[-2].ValueList; yyvsp[-2].ValueList->push_back(yyvsp[0].ValueVal); - ; - break;} -case 191: -#line 2008 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ yyval.ValueList = 0; ; - break;} -case 192: -#line 2010 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 205: +#line 2067 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ValueList = 0; ;} + break; + + case 206: +#line 2069 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.BoolVal = true; - ; - break;} -case 193: -#line 2013 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 207: +#line 2072 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.BoolVal = false; - ; - break;} -case 194: -#line 2019 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 208: +#line 2078 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (!(*yyvsp[-3].TypeVal)->isInteger() && !(*yyvsp[-3].TypeVal)->isFloatingPoint() && !isa((*yyvsp[-3].TypeVal).get())) ThrowException("Arithmetic operator requires integer, FP, or vector operands!"); @@ -3528,11 +4260,12 @@ if (yyval.InstVal == 0) ThrowException("binary operator returned null!"); delete yyvsp[-3].TypeVal; - ; - break;} -case 195: -#line 2032 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 209: +#line 2091 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (!(*yyvsp[-3].TypeVal)->isIntegral() && !(*yyvsp[-3].TypeVal)->isIntegralVector()) ThrowException("Logical operator requires integral operands!"); @@ -3540,29 +4273,32 @@ if (yyval.InstVal == 0) ThrowException("binary operator returned null!"); delete yyvsp[-3].TypeVal; - ; - break;} -case 196: -#line 2041 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 210: +#line 2100 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.InstVal = new SetCondInst(yyvsp[-4].BinaryOpVal, getVal(*yyvsp[-3].TypeVal, yyvsp[-2].ValIDVal), getVal(*yyvsp[-3].TypeVal, yyvsp[0].ValIDVal)); if (yyval.InstVal == 0) ThrowException("binary operator returned null!"); delete yyvsp[-3].TypeVal; - ; - break;} -case 197: -#line 2047 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 211: +#line 2106 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.InstVal = new SetCondInst(yyvsp[-4].BinaryOpVal, getVal(*yyvsp[-3].TypeVal, yyvsp[-2].ValIDVal), getVal(*yyvsp[-3].TypeVal, yyvsp[0].ValIDVal)); if (yyval.InstVal == 0) ThrowException("binary operator returned null!"); delete yyvsp[-3].TypeVal; - ; - break;} -case 198: -#line 2053 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 212: +#line 2112 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { std::cerr << "WARNING: Use of eliminated 'not' instruction:" << " Replacing with 'xor'.\n"; @@ -3573,42 +4309,46 @@ yyval.InstVal = BinaryOperator::create(Instruction::Xor, yyvsp[0].ValueVal, Ones); if (yyval.InstVal == 0) ThrowException("Could not create a xor instruction!"); - ; - break;} -case 199: -#line 2065 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 213: +#line 2124 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (yyvsp[0].ValueVal->getType() != Type::UByteTy) ThrowException("Shift amount must be ubyte!"); if (!yyvsp[-2].ValueVal->getType()->isInteger() && !yyvsp[-2].ValueVal->getType()->isIntegerVector()) ThrowException("Shift requires integer operand!"); yyval.InstVal = new ShiftInst(yyvsp[-3].OtherOpVal, yyvsp[-2].ValueVal, yyvsp[0].ValueVal); - ; - break;} -case 200: -#line 2073 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 214: +#line 2132 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (!yyvsp[0].TypeVal->get()->isFirstClassType()) ThrowException("cast instruction to a non-primitive type: '" + yyvsp[0].TypeVal->get()->getDescription() + "'!"); yyval.InstVal = new CastInst(yyvsp[-2].ValueVal, *yyvsp[0].TypeVal); delete yyvsp[0].TypeVal; - ; - break;} -case 201: -#line 2080 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 215: +#line 2139 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (yyvsp[-4].ValueVal->getType() != Type::BoolTy) ThrowException("select condition must be boolean!"); if (yyvsp[-2].ValueVal->getType() != yyvsp[0].ValueVal->getType()) ThrowException("select value types should match!"); yyval.InstVal = new SelectInst(yyvsp[-4].ValueVal, yyvsp[-2].ValueVal, yyvsp[0].ValueVal); - ; - break;} -case 202: -#line 2087 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 216: +#line 2146 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (!yyvsp[-4].ValueVal->getType()->isBooleanVector()) ThrowException("vselect condition must be boolean vector!"); if (yyvsp[-2].ValueVal->getType() != yyvsp[0].ValueVal->getType()) @@ -3616,23 +4356,25 @@ if (!isa(yyvsp[-2].ValueVal->getType())) ThrowException("vselect value must be a vector!"); yyval.InstVal = new VSelectInst(yyvsp[-4].ValueVal, yyvsp[-2].ValueVal, yyvsp[0].ValueVal); - ; - break;} -case 203: -#line 2096 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 217: +#line 2155 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { NewVarArgs = true; yyval.InstVal = new VAArgInst(yyvsp[-2].ValueVal, *yyvsp[0].TypeVal); delete yyvsp[0].TypeVal; - ; - break;} -case 204: -#line 2101 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 218: +#line 2160 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { ObsoleteVarArgs = true; const Type* ArgTy = yyvsp[-2].ValueVal->getType(); Function* NF = CurModule.CurrentModule-> - getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0); + getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0); //b = vaarg a, t -> //foo = alloca 1 of t @@ -3646,15 +4388,16 @@ CurBB->getInstList().push_back(new StoreInst(bar, foo)); yyval.InstVal = new VAArgInst(foo, *yyvsp[0].TypeVal); delete yyvsp[0].TypeVal; - ; - break;} -case 205: -#line 2120 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 219: +#line 2179 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { ObsoleteVarArgs = true; const Type* ArgTy = yyvsp[-2].ValueVal->getType(); Function* NF = CurModule.CurrentModule-> - getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0); + getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0); //b = vanext a, t -> //foo = alloca 1 of t @@ -3671,11 +4414,12 @@ CurBB->getInstList().push_back(tmp); yyval.InstVal = new LoadInst(foo); delete yyvsp[0].TypeVal; - ; - break;} -case 206: -#line 2142 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 220: +#line 2201 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { const Type *Ty = yyvsp[0].PHIList->front().first->getType(); if (!Ty->isFirstClassType()) ThrowException("PHI node operands must be of first class type!"); @@ -3688,11 +4432,12 @@ yyvsp[0].PHIList->pop_front(); } delete yyvsp[0].PHIList; // Free the list... - ; - break;} -case 207: -#line 2156 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 221: +#line 2215 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { const PointerType *PFTy; const FunctionType *Ty; @@ -3748,90 +4493,103 @@ cast(yyval.InstVal)->setCallingConv(yyvsp[-5].UIntVal); delete yyvsp[-4].TypeVal; delete yyvsp[-1].ValueList; - ; - break;} -case 208: -#line 2213 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 222: +#line 2272 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.InstVal = yyvsp[0].InstVal; - ; - break;} -case 209: -#line 2219 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 223: +#line 2278 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ValueList = yyvsp[0].ValueList; - ; - break;} -case 210: -#line 2221 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 224: +#line 2280 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.ValueList = new std::vector(); - ; - break;} -case 211: -#line 2225 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 225: +#line 2284 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.BoolVal = true; - ; - break;} -case 212: -#line 2228 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 226: +#line 2287 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.BoolVal = false; - ; - break;} -case 213: -#line 2232 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 227: +#line 2291 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.BoolVal = true; - ; - break;} -case 214: -#line 2235 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 228: +#line 2294 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { yyval.BoolVal = false; - ; - break;} -case 215: -#line 2240 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ - yyval.InstVal = new MallocInst(*yyvsp[0].TypeVal); - delete yyvsp[0].TypeVal; - ; - break;} -case 216: -#line 2244 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ - yyval.InstVal = new MallocInst(*yyvsp[-3].TypeVal, getVal(yyvsp[-1].PrimType, yyvsp[0].ValIDVal)); - delete yyvsp[-3].TypeVal; - ; - break;} -case 217: -#line 2248 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ - yyval.InstVal = new AllocaInst(*yyvsp[0].TypeVal); - delete yyvsp[0].TypeVal; - ; - break;} -case 218: -#line 2252 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ - yyval.InstVal = new AllocaInst(*yyvsp[-3].TypeVal, getVal(yyvsp[-1].PrimType, yyvsp[0].ValIDVal)); - delete yyvsp[-3].TypeVal; - ; - break;} -case 219: -#line 2256 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 229: +#line 2299 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + yyval.InstVal = new MallocInst(*yyvsp[-1].TypeVal, 0, yyvsp[0].UIntVal); + delete yyvsp[-1].TypeVal; + ;} + break; + + case 230: +#line 2303 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + yyval.InstVal = new MallocInst(*yyvsp[-4].TypeVal, getVal(yyvsp[-2].PrimType, yyvsp[-1].ValIDVal), yyvsp[0].UIntVal); + delete yyvsp[-4].TypeVal; + ;} + break; + + case 231: +#line 2307 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + yyval.InstVal = new AllocaInst(*yyvsp[-1].TypeVal, 0, yyvsp[0].UIntVal); + delete yyvsp[-1].TypeVal; + ;} + break; + + case 232: +#line 2311 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { + yyval.InstVal = new AllocaInst(*yyvsp[-4].TypeVal, getVal(yyvsp[-2].PrimType, yyvsp[-1].ValIDVal), yyvsp[0].UIntVal); + delete yyvsp[-4].TypeVal; + ;} + break; + + case 233: +#line 2315 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (!isa(yyvsp[0].ValueVal->getType())) ThrowException("Trying to free nonpointer type " + yyvsp[0].ValueVal->getType()->getDescription() + "!"); yyval.InstVal = new FreeInst(yyvsp[0].ValueVal); - ; - break;} -case 220: -#line 2263 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 234: +#line 2322 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (!isa(yyvsp[-1].TypeVal->get())) ThrowException("Can't load from nonpointer type: " + (*yyvsp[-1].TypeVal)->getDescription()); @@ -3840,11 +4598,12 @@ (*yyvsp[-1].TypeVal)->getDescription()); yyval.InstVal = new LoadInst(getVal(*yyvsp[-1].TypeVal, yyvsp[0].ValIDVal), "", yyvsp[-3].BoolVal); delete yyvsp[-1].TypeVal; - ; - break;} -case 221: -#line 2274 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 235: +#line 2333 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { const PointerType *PT = dyn_cast(yyvsp[-1].TypeVal->get()); if (!PT) ThrowException("Can't store to a nonpointer type: " + @@ -3856,11 +4615,12 @@ yyval.InstVal = new StoreInst(yyvsp[-3].ValueVal, getVal(*yyvsp[-1].TypeVal, yyvsp[0].ValIDVal), yyvsp[-5].BoolVal); delete yyvsp[-1].TypeVal; - ; - break;} -case 222: -#line 2288 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 236: +#line 2347 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (!isa(yyvsp[-2].TypeVal->get())) ThrowException("getelementptr insn requires pointer operand!"); @@ -3880,11 +4640,12 @@ (*yyvsp[-2].TypeVal)->getDescription()+ "'!"); yyval.InstVal = new GetElementPtrInst(getVal(*yyvsp[-2].TypeVal, yyvsp[-1].ValIDVal), *yyvsp[0].ValueList); delete yyvsp[-2].TypeVal; delete yyvsp[0].ValueList; - ; - break;} -case 223: -#line 2310 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 237: +#line 2369 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (!isa(yyvsp[-2].TypeVal->get())) ThrowException("Can't load vector from nonpointer type: " + (*yyvsp[-2].TypeVal)->getDescription()); @@ -3897,19 +4658,21 @@ ThrowException("vgather indices must be of type long!"); yyval.InstVal = new VGatherInst(getVal(*yyvsp[-2].TypeVal, yyvsp[-1].ValIDVal), *yyvsp[0].ValueList); delete yyvsp[-2].TypeVal; delete yyvsp[0].ValueList; - ; - break;} -case 224: -#line 2325 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 238: +#line 2384 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (yyvsp[0].ValueVal->getType() != Type::UIntTy) ThrowException("Length of vimm must be unsigned int!"); yyval.InstVal = new VImmInst(yyvsp[-2].ValueVal, yyvsp[0].ValueVal, yyvsp[-4].BoolVal); - ; - break;} -case 225: -#line 2331 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 239: +#line 2390 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (!isa(yyvsp[-6].ValueVal->getType())) ThrowException("First operand of extract must be a vector!"); if (yyvsp[-4].ValueVal->getType() != Type::UIntTy) @@ -3919,21 +4682,23 @@ if (yyvsp[0].ValueVal->getType() != Type::UIntTy) ThrowException("Fourth operand of extract must be a uint!"); yyval.InstVal = new ExtractInst(yyvsp[-6].ValueVal, yyvsp[-4].ValueVal, yyvsp[-2].ValueVal, yyvsp[0].ValueVal); - ; - break;} -case 226: -#line 2343 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 240: +#line 2402 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (!isa(yyvsp[-2].ValueVal->getType())) ThrowException("First operand of extractelement must be a vector!"); if (yyvsp[0].ValueVal->getType() != Type::UIntTy) ThrowException("Second operand of extractelement must be a uint!"); yyval.InstVal = new ExtractElementInst(yyvsp[-2].ValueVal, yyvsp[0].ValueVal); - ; - break;} -case 227: -#line 2351 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 241: +#line 2410 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (!isa(yyvsp[-6].ValueVal->getType())) ThrowException("First operand of combine must be a vector!"); if (!isa(yyvsp[-4].ValueVal->getType())) @@ -3943,11 +4708,12 @@ if (yyvsp[0].ValueVal->getType() != Type::UIntTy) ThrowException("Fourth operand of combine must be a uint!"); yyval.InstVal = new CombineInst(yyvsp[-6].ValueVal, yyvsp[-4].ValueVal, yyvsp[-2].ValueVal, yyvsp[0].ValueVal); - ; - break;} -case 228: -#line 2363 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 242: +#line 2422 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (!isa(yyvsp[-4].ValueVal->getType())) ThrowException("First operand of combineelement must be a vector!"); if (yyvsp[-2].ValueVal->getType() != cast(yyvsp[-4].ValueVal->getType())->getElementType()) @@ -3955,11 +4721,12 @@ if (yyvsp[0].ValueVal->getType() != Type::UIntTy) ThrowException("Third operand of combineelement must be a uint!"); yyval.InstVal = new CombineElementInst(yyvsp[-4].ValueVal, yyvsp[-2].ValueVal, yyvsp[0].ValueVal); - ; - break;} -case 229: -#line 2373 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" -{ + ;} + break; + + case 243: +#line 2432 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" + { if (!isa(yyvsp[-2].TypeVal->get())) ThrowException("Can't store to a nonpointer type: " + (*yyvsp[-2].TypeVal)->getDescription()); @@ -3989,231 +4756,208 @@ "' into space of type '" + VT->getDescription() + "'!"); yyval.InstVal = new VScatterInst(yyvsp[-4].ValueVal, getVal(*yyvsp[-2].TypeVal, yyvsp[-1].ValIDVal), *yyvsp[0].ValueList); delete yyvsp[-2].TypeVal; delete yyvsp[0].ValueList; - ; - break;} -} - /* the action file gets copied in in place of this dollarsign */ -#line 543 "/usr/share/bison.simple" + ;} + break; + + + } + +/* Line 999 of yacc.c. */ +#line 4766 "llvmAsmParser.tab.c" yyvsp -= yylen; yyssp -= yylen; -#ifdef YYLSP_NEEDED - yylsp -= yylen; -#endif -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif + + YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; -#ifdef YYLSP_NEEDED - yylsp++; - if (yylen == 0) - { - yylsp->first_line = yylloc.first_line; - yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; - yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } -#endif - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ yyn = yyr1[yyn]; - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else - yystate = yydefgoto[yyn - YYNTBASE]; + yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; -yyerrlab: /* here on detecting error */ - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) { ++yynerrs; - -#ifdef YYERROR_VERBOSE +#if YYERROR_VERBOSE yyn = yypact[yystate]; - if (yyn > YYFLAG && yyn < YYLAST) + if (YYPACT_NINF < yyn && yyn < YYLAST) { - int size = 0; - char *msg; - int x, count; - - count = 0; - /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; - msg = (char *) malloc(size + 15); - if (msg != 0) + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + char *yymsg; + int yyx, yycount; + + yycount = 0; + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + yysize += yystrlen (yytname[yyx]) + 15, yycount++; + yysize += yystrlen ("syntax error, unexpected ") + 1; + yysize += yystrlen (yytname[yytype]); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) { - strcpy(msg, "parse error"); + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); - if (count < 5) + if (yycount < 5) { - count = 0; - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) + yycount = 0; + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); + yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; + const char *yyq = ! yycount ? ", expecting " : " or "; + yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yytname[yyx]); + yycount++; } } - yyerror(msg); - free(msg); + yyerror (yymsg); + YYSTACK_FREE (yymsg); } else - yyerror ("parse error; also virtual memory exceeded"); + yyerror ("syntax error; also virtual memory exhausted"); } else #endif /* YYERROR_VERBOSE */ - yyerror("parse error"); + yyerror ("syntax error"); } - goto yyerrlab1; -yyerrlab1: /* here on error raised explicitly by an action */ + if (yyerrstatus == 3) { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ - /* return failure if at end of input */ + /* Return failure if at end of input. */ if (yychar == YYEOF) - YYABORT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); -#endif + { + /* Pop the error token. */ + YYPOPSTACK; + /* Pop the rest of the stack. */ + while (yyss < yyssp) + { + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); + YYPOPSTACK; + } + YYABORT; + } + YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); + yydestruct (yytoken, &yylval); yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token - after shifting the error token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; -yyerrdefault: /* current state does not do anything special for the error token. */ + } -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; -#endif + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; -yyerrpop: /* pop the current state because it cannot handle the error token */ - if (yyssp == yyss) YYABORT; - yyvsp--; - yystate = *--yyssp; -#ifdef YYLSP_NEEDED - yylsp--; -#endif +/*----------------------------------------------------. +| yyerrlab1 -- error raised explicitly by an action. | +`----------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ -#if YYDEBUG != 0 - if (yydebug) + for (;;) { - short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - -yyerrhandle: + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + yyvsp--; + yystate = *--yyssp; - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; + YY_STACK_PRINT (yyss, yyssp); } - else if (yyn == 0) - goto yyerrpop; if (yyn == YYFINAL) YYACCEPT; -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting error token, "); -#endif + YYDPRINTF ((stderr, "Shifting error token, ")); *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif + yystate = yyn; goto yynewstate; - yyacceptlab: - /* YYACCEPT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 0; - yyabortlab: - /* YYABORT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); #endif - } - return 1; + return yyresult; } -#line 2406 "/Users/bocchino/llvm/obj/../src/lib/AsmParser/llvmAsmParser.y" + + +#line 2465 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" int yyerror(const char *ErrorMsg) { std::string where @@ -4227,3 +4971,4 @@ ThrowException(errMsg); return 0; } + Index: llvm/lib/AsmParser/llvmAsmParser.h diff -u llvm/lib/AsmParser/llvmAsmParser.h:1.9.2.1 llvm/lib/AsmParser/llvmAsmParser.h:1.9.2.2 --- llvm/lib/AsmParser/llvmAsmParser.h:1.9.2.1 Tue Oct 18 14:21:56 2005 +++ llvm/lib/AsmParser/llvmAsmParser.h Wed Nov 16 12:32:08 2005 @@ -1,4 +1,263 @@ -typedef union { +/* A Bison parser, made by GNU Bison 1.875. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + ESINT64VAL = 258, + EUINT64VAL = 259, + SINTVAL = 260, + UINTVAL = 261, + FPVAL = 262, + VOID = 263, + BOOL = 264, + SBYTE = 265, + UBYTE = 266, + SHORT = 267, + USHORT = 268, + INT = 269, + UINT = 270, + LONG = 271, + ULONG = 272, + FLOAT = 273, + DOUBLE = 274, + TYPE = 275, + LABEL = 276, + VAR_ID = 277, + LABELSTR = 278, + STRINGCONSTANT = 279, + IMPLEMENTATION = 280, + ZEROINITIALIZER = 281, + TRUETOK = 282, + FALSETOK = 283, + BEGINTOK = 284, + ENDTOK = 285, + DECLARE = 286, + GLOBAL = 287, + CONSTANT = 288, + SECTION = 289, + VOLATILE = 290, + FIXED = 291, + TO = 292, + DOTDOTDOT = 293, + NULL_TOK = 294, + UNDEF = 295, + CONST = 296, + INTERNAL = 297, + LINKONCE = 298, + WEAK = 299, + APPENDING = 300, + OPAQUE = 301, + NOT = 302, + EXTERNAL = 303, + TARGET = 304, + TRIPLE = 305, + ENDIAN = 306, + POINTERSIZE = 307, + LITTLE = 308, + BIG = 309, + ALIGN = 310, + DEPLIBS = 311, + CALL = 312, + TAIL = 313, + CC_TOK = 314, + CCC_TOK = 315, + FASTCC_TOK = 316, + COLDCC_TOK = 317, + VECTOR = 318, + OF = 319, + RET = 320, + BR = 321, + SWITCH = 322, + INVOKE = 323, + UNWIND = 324, + UNREACHABLE = 325, + ADD = 326, + SUB = 327, + MUL = 328, + DIV = 329, + REM = 330, + AND = 331, + OR = 332, + XOR = 333, + SETLE = 334, + SETGE = 335, + SETLT = 336, + SETGT = 337, + SETEQ = 338, + SETNE = 339, + VSETLE = 340, + VSETGE = 341, + VSETLT = 342, + VSETGT = 343, + VSETEQ = 344, + VSETNE = 345, + MALLOC = 346, + ALLOCA = 347, + FREE = 348, + LOAD = 349, + STORE = 350, + GETELEMENTPTR = 351, + PHI_TOK = 352, + CAST = 353, + SELECT = 354, + VSELECT = 355, + SHL = 356, + SHR = 357, + VAARG = 358, + VGATHER = 359, + VIMM = 360, + VSCATTER = 361, + EXTRACT = 362, + EXTRACTELEMENT = 363, + COMBINE = 364, + COMBINEELEMENT = 365, + VAARG_old = 366, + VANEXT_old = 367 + }; +#endif +#define ESINT64VAL 258 +#define EUINT64VAL 259 +#define SINTVAL 260 +#define UINTVAL 261 +#define FPVAL 262 +#define VOID 263 +#define BOOL 264 +#define SBYTE 265 +#define UBYTE 266 +#define SHORT 267 +#define USHORT 268 +#define INT 269 +#define UINT 270 +#define LONG 271 +#define ULONG 272 +#define FLOAT 273 +#define DOUBLE 274 +#define TYPE 275 +#define LABEL 276 +#define VAR_ID 277 +#define LABELSTR 278 +#define STRINGCONSTANT 279 +#define IMPLEMENTATION 280 +#define ZEROINITIALIZER 281 +#define TRUETOK 282 +#define FALSETOK 283 +#define BEGINTOK 284 +#define ENDTOK 285 +#define DECLARE 286 +#define GLOBAL 287 +#define CONSTANT 288 +#define SECTION 289 +#define VOLATILE 290 +#define FIXED 291 +#define TO 292 +#define DOTDOTDOT 293 +#define NULL_TOK 294 +#define UNDEF 295 +#define CONST 296 +#define INTERNAL 297 +#define LINKONCE 298 +#define WEAK 299 +#define APPENDING 300 +#define OPAQUE 301 +#define NOT 302 +#define EXTERNAL 303 +#define TARGET 304 +#define TRIPLE 305 +#define ENDIAN 306 +#define POINTERSIZE 307 +#define LITTLE 308 +#define BIG 309 +#define ALIGN 310 +#define DEPLIBS 311 +#define CALL 312 +#define TAIL 313 +#define CC_TOK 314 +#define CCC_TOK 315 +#define FASTCC_TOK 316 +#define COLDCC_TOK 317 +#define VECTOR 318 +#define OF 319 +#define RET 320 +#define BR 321 +#define SWITCH 322 +#define INVOKE 323 +#define UNWIND 324 +#define UNREACHABLE 325 +#define ADD 326 +#define SUB 327 +#define MUL 328 +#define DIV 329 +#define REM 330 +#define AND 331 +#define OR 332 +#define XOR 333 +#define SETLE 334 +#define SETGE 335 +#define SETLT 336 +#define SETGT 337 +#define SETEQ 338 +#define SETNE 339 +#define VSETLE 340 +#define VSETGE 341 +#define VSETLT 342 +#define VSETGT 343 +#define VSETEQ 344 +#define VSETNE 345 +#define MALLOC 346 +#define ALLOCA 347 +#define FREE 348 +#define LOAD 349 +#define STORE 350 +#define GETELEMENTPTR 351 +#define PHI_TOK 352 +#define CAST 353 +#define SELECT 354 +#define VSELECT 355 +#define SHL 356 +#define SHR 357 +#define VAARG 358 +#define VGATHER 359 +#define VIMM 360 +#define VSCATTER 361 +#define EXTRACT 362 +#define EXTRACTELEMENT 363 +#define COMBINE 364 +#define COMBINEELEMENT 365 +#define VAARG_old 366 +#define VANEXT_old 367 + + + + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 870 "/home/vadve/bocchino/llvm/src/lib/AsmParser/llvmAsmParser.y" +typedef union YYSTYPE { llvm::Module *ModuleVal; llvm::Function *FunctionVal; std::pair *ArgVal; @@ -37,114 +296,14 @@ llvm::Instruction::OtherOps OtherOpVal; llvm::Module::Endianness Endianness; } YYSTYPE; -#define ESINT64VAL 257 -#define EUINT64VAL 258 -#define SINTVAL 259 -#define UINTVAL 260 -#define FPVAL 261 -#define VOID 262 -#define BOOL 263 -#define SBYTE 264 -#define UBYTE 265 -#define SHORT 266 -#define USHORT 267 -#define INT 268 -#define UINT 269 -#define LONG 270 -#define ULONG 271 -#define FLOAT 272 -#define DOUBLE 273 -#define TYPE 274 -#define LABEL 275 -#define VAR_ID 276 -#define LABELSTR 277 -#define STRINGCONSTANT 278 -#define IMPLEMENTATION 279 -#define ZEROINITIALIZER 280 -#define TRUETOK 281 -#define FALSETOK 282 -#define BEGINTOK 283 -#define ENDTOK 284 -#define DECLARE 285 -#define GLOBAL 286 -#define CONSTANT 287 -#define VOLATILE 288 -#define FIXED 289 -#define TO 290 -#define DOTDOTDOT 291 -#define NULL_TOK 292 -#define UNDEF 293 -#define CONST 294 -#define INTERNAL 295 -#define LINKONCE 296 -#define WEAK 297 -#define APPENDING 298 -#define OPAQUE 299 -#define NOT 300 -#define EXTERNAL 301 -#define TARGET 302 -#define TRIPLE 303 -#define ENDIAN 304 -#define POINTERSIZE 305 -#define LITTLE 306 -#define BIG 307 -#define DEPLIBS 308 -#define CALL 309 -#define TAIL 310 -#define CC_TOK 311 -#define CCC_TOK 312 -#define FASTCC_TOK 313 -#define COLDCC_TOK 314 -#define VECTOR 315 -#define OF 316 -#define RET 317 -#define BR 318 -#define SWITCH 319 -#define INVOKE 320 -#define UNWIND 321 -#define UNREACHABLE 322 -#define ADD 323 -#define SUB 324 -#define MUL 325 -#define DIV 326 -#define REM 327 -#define AND 328 -#define OR 329 -#define XOR 330 -#define SETLE 331 -#define SETGE 332 -#define SETLT 333 -#define SETGT 334 -#define SETEQ 335 -#define SETNE 336 -#define VSETLE 337 -#define VSETGE 338 -#define VSETLT 339 -#define VSETGT 340 -#define VSETEQ 341 -#define VSETNE 342 -#define MALLOC 343 -#define ALLOCA 344 -#define FREE 345 -#define LOAD 346 -#define STORE 347 -#define GETELEMENTPTR 348 -#define PHI_TOK 349 -#define CAST 350 -#define SELECT 351 -#define VSELECT 352 -#define SHL 353 -#define SHR 354 -#define VAARG 355 -#define VGATHER 356 -#define VIMM 357 -#define VSCATTER 358 -#define EXTRACT 359 -#define EXTRACTELEMENT 360 -#define COMBINE 361 -#define COMBINEELEMENT 362 -#define VAARG_old 363 -#define VANEXT_old 364 - +/* Line 1240 of yacc.c. */ +#line 300 "llvmAsmParser.tab.h" +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif extern YYSTYPE llvmAsmlval; + + + Index: llvm/lib/AsmParser/llvmAsmParser.y diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.231.2.1 llvm/lib/AsmParser/llvmAsmParser.y:1.231.2.2 --- llvm/lib/AsmParser/llvmAsmParser.y:1.231.2.1 Tue Oct 18 14:21:56 2005 +++ llvm/lib/AsmParser/llvmAsmParser.y Wed Nov 16 12:32:08 2005 @@ -19,6 +19,7 @@ #include "llvm/SymbolTable.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/MathExtras.h" #include #include #include @@ -49,7 +50,8 @@ static bool ObsoleteVarArgs; static bool NewVarArgs; -static BasicBlock* CurBB; +static BasicBlock *CurBB; +static GlobalVariable *CurGV; // This contains info used when building the body of a function. It is @@ -514,9 +516,10 @@ /// ParseGlobalVariable - Handle parsing of a global. If Initializer is null, /// this is a declaration, otherwise it is a definition. -static void ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage, - bool isConstantGlobal, const Type *Ty, - Constant *Initializer) { +static GlobalVariable * +ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage, + bool isConstantGlobal, const Type *Ty, + Constant *Initializer) { if (isa(Ty)) ThrowException("Cannot declare global vars of function type!"); @@ -547,7 +550,7 @@ GV->setLinkage(Linkage); GV->setConstant(isConstantGlobal); InsertValue(GV, CurModule.Values); - return; + return GV; } // If this global has a name, check to see if there is already a definition @@ -572,7 +575,7 @@ if (isConstantGlobal) EGV->setConstant(true); EGV->setLinkage(Linkage); - return; + return EGV; } ThrowException("Redefinition of global variable named '" + Name + @@ -585,6 +588,7 @@ new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name, CurModule.CurrentModule); InsertValue(GV, CurModule.Values); + return GV; } // setTypeName - Set the specified type to the name given. The name may be @@ -766,7 +770,7 @@ const Type* ArgTy = F->getFunctionType()->getReturnType(); const Type* ArgTyPtr = PointerType::get(ArgTy); Function* NF = Result->getOrInsertFunction("llvm.va_start", - RetTy, ArgTyPtr, 0); + RetTy, ArgTyPtr, (Type *)0); while (!F->use_empty()) { CallInst* CI = cast(F->use_back()); @@ -791,7 +795,7 @@ const Type* ArgTy = F->getFunctionType()->getParamType(0); const Type* ArgTyPtr = PointerType::get(ArgTy); Function* NF = Result->getOrInsertFunction("llvm.va_end", - RetTy, ArgTyPtr, 0); + RetTy, ArgTyPtr, (Type *)0); while (!F->use_empty()) { CallInst* CI = cast(F->use_back()); @@ -818,7 +822,8 @@ const Type* ArgTy = F->getFunctionType()->getReturnType(); const Type* ArgTyPtr = PointerType::get(ArgTy); Function* NF = Result->getOrInsertFunction("llvm.va_copy", - RetTy, ArgTyPtr, ArgTyPtr, 0); + RetTy, ArgTyPtr, ArgTyPtr, + (Type *)0); while (!F->use_empty()) { CallInst* CI = cast(F->use_back()); @@ -948,12 +953,13 @@ %token VAR_ID LABELSTR STRINGCONSTANT %type Name OptName OptAssign - +%type OptAlign OptCAlign +%type OptSection SectionString %token IMPLEMENTATION ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK -%token DECLARE GLOBAL CONSTANT VOLATILE FIXED +%token DECLARE GLOBAL CONSTANT SECTION VOLATILE FIXED %token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK APPENDING -%token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG +%token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN %token DEPLIBS CALL TAIL %token CC_TOK CCC_TOK FASTCC_TOK COLDCC_TOK %token VECTOR OF @@ -1039,6 +1045,47 @@ $$ = $2; }; +// OptAlign/OptCAlign - An optional alignment, and an optional alignment with +// a comma before it. +OptAlign : /*empty*/ { $$ = 0; } | + ALIGN EUINT64VAL { + $$ = $2; + if ($$ != 0 && !isPowerOf2_32($$)) + ThrowException("Alignment must be a power of two!"); +}; +OptCAlign : /*empty*/ { $$ = 0; } | + ',' ALIGN EUINT64VAL { + $$ = $3; + if ($$ != 0 && !isPowerOf2_32($$)) + ThrowException("Alignment must be a power of two!"); +}; + + +SectionString : SECTION STRINGCONSTANT { + for (unsigned i = 0, e = strlen($2); i != e; ++i) + if ($2[i] == '"' || $2[i] == '\\') + ThrowException("Invalid character in section name!"); + $$ = $2; +}; + +OptSection : /*empty*/ { $$ = 0; } | + SectionString { $$ = $1; }; + +// GlobalVarAttributes - Used to pass the attributes string on a global. CurGV +// is set to be the global we are processing. +// +GlobalVarAttributes : /* empty */ {} | + ',' GlobalVarAttribute GlobalVarAttributes {}; +GlobalVarAttribute : SectionString { + CurGV->setSection($1); + free($1); + } + | ALIGN EUINT64VAL { + if ($2 != 0 && !isPowerOf2_32($2)) + ThrowException("Alignment must be a power of two!"); + CurGV->setAlignment($2); + }; + //===----------------------------------------------------------------------===// // Types includes all predefined types... except void, because it can only be // used in specific contexts (function returning void for example). To have @@ -1095,7 +1142,6 @@ $$ = new PATypeHolder(HandleUpRefs(ArrayType::get(*$4, (unsigned)$2))); delete $4; } - | '[' VECTOR OF UpRTypes ']' { // Vector type? $$ = new PATypeHolder(HandleUpRefs(VectorType::get(*$4))); delete $4; @@ -1109,6 +1155,8 @@ if(!ElemTy->isPrimitiveType()) { ThrowException("Element type of a FixedVectorType must be primitive"); } + //if (!isPowerOf2_32($2)) + // ThrowException("Vector length should be a power of 2!"); $$ = new PATypeHolder(HandleUpRefs(FixedVectorType::get(*$5, (unsigned)$4))); delete $5; } @@ -1559,11 +1607,16 @@ } | ConstPool OptAssign OptLinkage GlobalType ConstVal { if ($5 == 0) ThrowException("Global value initializer is not a constant!"); - ParseGlobalVariable($2, $3, $4, $5->getType(), $5); + CurGV = ParseGlobalVariable($2, $3, $4, $5->getType(), $5); + } GlobalVarAttributes { + CurGV = 0; } | ConstPool OptAssign EXTERNAL GlobalType Types { - ParseGlobalVariable($2, GlobalValue::ExternalLinkage, $4, *$5, 0); + CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage, + $4, *$5, 0); delete $5; + } GlobalVarAttributes { + CurGV = 0; } | ConstPool TARGET TargetDefinition { } @@ -1647,7 +1700,8 @@ $$ = 0; }; -FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')' { +FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')' + OptSection OptAlign { UnEscapeLexed($3); std::string FunctionName($3); free($3); // Free strdup'd memory! @@ -1705,6 +1759,11 @@ CurFun.FunctionStart(Fn); Fn->setCallingConv($1); + Fn->setAlignment($8); + if ($7) { + Fn->setSection($7); + free($7); + } // Add all of the arguments we parsed to the function... if ($5) { // Is null if empty... @@ -2102,7 +2161,7 @@ ObsoleteVarArgs = true; const Type* ArgTy = $2->getType(); Function* NF = CurModule.CurrentModule-> - getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0); + getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0); //b = vaarg a, t -> //foo = alloca 1 of t @@ -2121,7 +2180,7 @@ ObsoleteVarArgs = true; const Type* ArgTy = $2->getType(); Function* NF = CurModule.CurrentModule-> - getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0); + getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0); //b = vanext a, t -> //foo = alloca 1 of t @@ -2237,20 +2296,20 @@ }; -MemoryInst : MALLOC Types { - $$ = new MallocInst(*$2); +MemoryInst : MALLOC Types OptCAlign { + $$ = new MallocInst(*$2, 0, $3); delete $2; } - | MALLOC Types ',' UINT ValueRef { - $$ = new MallocInst(*$2, getVal($4, $5)); + | MALLOC Types ',' UINT ValueRef OptCAlign { + $$ = new MallocInst(*$2, getVal($4, $5), $6); delete $2; } - | ALLOCA Types { - $$ = new AllocaInst(*$2); + | ALLOCA Types OptCAlign { + $$ = new AllocaInst(*$2, 0, $3); delete $2; } - | ALLOCA Types ',' UINT ValueRef { - $$ = new AllocaInst(*$2, getVal($4, $5)); + | ALLOCA Types ',' UINT ValueRef OptCAlign { + $$ = new AllocaInst(*$2, getVal($4, $5), $6); delete $2; } | FREE ResolvedVal { From bocchino at cs.uiuc.edu Wed Nov 16 12:32:52 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:52 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Target/SparcV8/SparcV8CodeEmitter.cpp SparcV8ISelPattern.cpp SparcV8TargetMachine.cpp SparcV8TargetMachine.h Message-ID: <200511161832.MAA21168@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8CodeEmitter.cpp updated: 1.4 -> 1.4.4.1 SparcV8ISelPattern.cpp (r1.7) removed SparcV8TargetMachine.cpp updated: 1.29 -> 1.29.2.1 SparcV8TargetMachine.h updated: 1.7 -> 1.7.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+4 -16) SparcV8CodeEmitter.cpp | 5 +---- SparcV8TargetMachine.cpp | 7 ++----- SparcV8TargetMachine.h | 8 +------- 3 files changed, 4 insertions(+), 16 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8CodeEmitter.cpp diff -u llvm/lib/Target/SparcV8/SparcV8CodeEmitter.cpp:1.4 llvm/lib/Target/SparcV8/SparcV8CodeEmitter.cpp:1.4.4.1 --- llvm/lib/Target/SparcV8/SparcV8CodeEmitter.cpp:1.4 Thu Apr 21 18:21:30 2005 +++ llvm/lib/Target/SparcV8/SparcV8CodeEmitter.cpp Wed Nov 16 12:32:40 2005 @@ -20,8 +20,7 @@ #include #include #include - -namespace llvm { +using namespace llvm; namespace { class SparcV8CodeEmitter : public MachineFunctionPass { @@ -182,5 +181,3 @@ } #include "SparcV8GenCodeEmitter.inc" - -} // end llvm namespace Index: llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp diff -u llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp:1.29 llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp:1.29.2.1 --- llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp:1.29 Thu Sep 1 16:38:21 2005 +++ llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp Wed Nov 16 12:32:40 2005 @@ -65,7 +65,8 @@ /// bool SparcV8TargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType) { + CodeGenFileType FileType, + bool Fast) { if (FileType != TargetMachine::AssemblyFile) return true; // FIXME: Implement efficient support for garbage collection intrinsics. @@ -80,8 +81,6 @@ // FIXME: implement the invoke/unwind instructions! PM.add(createLowerInvokePass()); - PM.add(createLowerConstantExpressionsPass()); - // Make sure that no unreachable blocks are instruction selected. PM.add(createUnreachableBlockEliminationPass()); @@ -137,8 +136,6 @@ // FIXME: implement the invoke/unwind instructions! PM.add(createLowerInvokePass()); - PM.add(createLowerConstantExpressionsPass()); - // Make sure that no unreachable blocks are instruction selected. PM.add(createUnreachableBlockEliminationPass()); Index: llvm/lib/Target/SparcV8/SparcV8TargetMachine.h diff -u llvm/lib/Target/SparcV8/SparcV8TargetMachine.h:1.7 llvm/lib/Target/SparcV8/SparcV8TargetMachine.h:1.7.2.1 --- llvm/lib/Target/SparcV8/SparcV8TargetMachine.h:1.7 Thu Sep 1 16:38:21 2005 +++ llvm/lib/Target/SparcV8/SparcV8TargetMachine.h Wed Nov 16 12:32:40 2005 @@ -45,17 +45,11 @@ static unsigned getModuleMatchQuality(const Module &M); static unsigned getJITMatchQuality(); - /// addPassesToEmitMachineCode - Add passes to the specified pass manager to - /// get machine code emitted. This uses a MachineCodeEmitter object to handle - /// actually outputting the machine code and resolving things like the address - /// of functions. This method should returns true if machine code emission is - /// not supported. - /// virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM, MachineCodeEmitter &MCE); virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType); + CodeGenFileType FileType, bool Fast); }; } // end namespace llvm From bocchino at cs.uiuc.edu Wed Nov 16 12:32:55 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:55 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Target/SparcV9/RegAlloc/Makefile Notes.txt Message-ID: <200511161832.MAA21184@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/RegAlloc: Makefile updated: 1.7 -> 1.7.6.1 Notes.txt (r1.2) removed --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+0 -1) Makefile | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/Target/SparcV9/RegAlloc/Makefile diff -u llvm/lib/Target/SparcV9/RegAlloc/Makefile:1.7 llvm/lib/Target/SparcV9/RegAlloc/Makefile:1.7.6.1 --- llvm/lib/Target/SparcV9/RegAlloc/Makefile:1.7 Wed Oct 27 18:18:45 2004 +++ llvm/lib/Target/SparcV9/RegAlloc/Makefile Wed Nov 16 12:32:43 2005 @@ -10,6 +10,5 @@ LEVEL = ../../../.. DIRS = LIBRARYNAME = LLVMSparcV9RegAlloc -BUILD_ARCHIVE = 1 include $(LEVEL)/Makefile.common From bocchino at cs.uiuc.edu Wed Nov 16 12:32:58 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:58 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Transforms/ExprTypeConvert.cpp Makefile TransformInternals.cpp Message-ID: <200511161832.MAA21226@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms: ExprTypeConvert.cpp updated: 1.107 -> 1.107.2.1 Makefile updated: 1.9.6.2 -> 1.9.6.3 TransformInternals.cpp updated: 1.49 -> 1.49.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+1 -121) ExprTypeConvert.cpp | 120 ------------------------------------------------- Makefile | 1 TransformInternals.cpp | 1 3 files changed, 1 insertion(+), 121 deletions(-) Index: llvm/lib/Transforms/ExprTypeConvert.cpp diff -u llvm/lib/Transforms/ExprTypeConvert.cpp:1.107 llvm/lib/Transforms/ExprTypeConvert.cpp:1.107.2.1 --- llvm/lib/Transforms/ExprTypeConvert.cpp:1.107 Tue Jul 26 11:38:28 2005 +++ llvm/lib/Transforms/ExprTypeConvert.cpp Wed Nov 16 12:32:47 2005 @@ -16,7 +16,6 @@ #include "TransformInternals.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" -#include "llvm/Analysis/Expressions.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Debug.h" #include @@ -29,115 +28,6 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, ValueMapCache &VMC, const TargetData &TD); -// Peephole Malloc instructions: we take a look at the use chain of the -// malloc instruction, and try to find out if the following conditions hold: -// 1. The malloc is of the form: 'malloc [sbyte], uint ' -// 2. The only users of the malloc are cast & add instructions -// 3. Of the cast instructions, there is only one destination pointer type -// [RTy] where the size of the pointed to object is equal to the number -// of bytes allocated. -// -// If these conditions hold, we convert the malloc to allocate an [RTy] -// element. TODO: This comment is out of date WRT arrays -// -static bool MallocConvertibleToType(MallocInst *MI, const Type *Ty, - ValueTypeCache &CTMap, - const TargetData &TD) { - if (!isa(Ty)) return false; // Malloc always returns pointers - - // Deal with the type to allocate, not the pointer type... - Ty = cast(Ty)->getElementType(); - if (!Ty->isSized() || !MI->getType()->getElementType()->isSized()) - return false; // Can only alloc something with a size - - // Analyze the number of bytes allocated... - ExprType Expr = ClassifyExpr(MI->getArraySize()); - - // Get information about the base datatype being allocated, before & after - uint64_t ReqTypeSize = TD.getTypeSize(Ty); - if (ReqTypeSize == 0) return false; - uint64_t OldTypeSize = TD.getTypeSize(MI->getType()->getElementType()); - - // Must have a scale or offset to analyze it... - if (!Expr.Offset && !Expr.Scale && OldTypeSize == 1) return false; - - // Get the offset and scale of the allocation... - int64_t OffsetVal = Expr.Offset ? getConstantValue(Expr.Offset) : 0; - int64_t ScaleVal = Expr.Scale ? getConstantValue(Expr.Scale) :(Expr.Var != 0); - - // The old type might not be of unit size, take old size into consideration - // here... - uint64_t Offset = OffsetVal * OldTypeSize; - uint64_t Scale = ScaleVal * OldTypeSize; - - // In order to be successful, both the scale and the offset must be a multiple - // of the requested data type's size. - // - if (Offset/ReqTypeSize*ReqTypeSize != Offset || - Scale/ReqTypeSize*ReqTypeSize != Scale) - return false; // Nope. - - return true; -} - -static Instruction *ConvertMallocToType(MallocInst *MI, const Type *Ty, - const std::string &Name, - ValueMapCache &VMC, - const TargetData &TD){ - BasicBlock *BB = MI->getParent(); - BasicBlock::iterator It = BB->end(); - - // Analyze the number of bytes allocated... - ExprType Expr = ClassifyExpr(MI->getArraySize()); - - const PointerType *AllocTy = cast(Ty); - const Type *ElType = AllocTy->getElementType(); - - uint64_t DataSize = TD.getTypeSize(ElType); - uint64_t OldTypeSize = TD.getTypeSize(MI->getType()->getElementType()); - - // Get the offset and scale coefficients that we are allocating... - int64_t OffsetVal = (Expr.Offset ? getConstantValue(Expr.Offset) : 0); - int64_t ScaleVal = Expr.Scale ? getConstantValue(Expr.Scale) : (Expr.Var !=0); - - // The old type might not be of unit size, take old size into consideration - // here... - unsigned Offset = OffsetVal * OldTypeSize / DataSize; - unsigned Scale = ScaleVal * OldTypeSize / DataSize; - - // Locate the malloc instruction, because we may be inserting instructions - It = MI; - - // If we have a scale, apply it first... - if (Expr.Var) { - // Expr.Var is not necessarily unsigned right now, insert a cast now. - if (Expr.Var->getType() != Type::UIntTy) - Expr.Var = new CastInst(Expr.Var, Type::UIntTy, - Expr.Var->getName()+"-uint", It); - - if (Scale != 1) - Expr.Var = BinaryOperator::create(Instruction::Mul, Expr.Var, - ConstantUInt::get(Type::UIntTy, Scale), - Expr.Var->getName()+"-scl", It); - - } else { - // If we are not scaling anything, just make the offset be the "var"... - Expr.Var = ConstantUInt::get(Type::UIntTy, Offset); - Offset = 0; Scale = 1; - } - - // If we have an offset now, add it in... - if (Offset != 0) { - assert(Expr.Var && "Var must be nonnull by now!"); - Expr.Var = BinaryOperator::create(Instruction::Add, Expr.Var, - ConstantUInt::get(Type::UIntTy, Offset), - Expr.Var->getName()+"-off", It); - } - - assert(AllocTy == Ty); - return new MallocInst(AllocTy->getElementType(), Expr.Var, Name); -} - // ExpressionConvertibleToType - Return true if it is possible bool llvm::ExpressionConvertibleToType(Value *V, const Type *Ty, @@ -213,11 +103,6 @@ break; } - case Instruction::Malloc: - if (!MallocConvertibleToType(cast(I), Ty, CTMap, TD)) - return false; - break; - case Instruction::GetElementPtr: { // GetElementPtr's are directly convertible to a pointer type if they have // a number of zeros at the end. Because removing these values does not @@ -396,11 +281,6 @@ break; } - case Instruction::Malloc: { - Res = ConvertMallocToType(cast(I), Ty, Name, VMC, TD); - break; - } - case Instruction::GetElementPtr: { // GetElementPtr's are directly convertible to a pointer type if they have // a number of zeros at the end. Because removing these values does not Index: llvm/lib/Transforms/Makefile diff -u llvm/lib/Transforms/Makefile:1.9.6.2 llvm/lib/Transforms/Makefile:1.9.6.3 --- llvm/lib/Transforms/Makefile:1.9.6.2 Tue Oct 18 14:50:38 2005 +++ llvm/lib/Transforms/Makefile Wed Nov 16 12:32:47 2005 @@ -6,6 +6,7 @@ # the University of Illinois Open Source License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## + LEVEL = ../.. PARALLEL_DIRS = Utils Instrumentation Scalar IPO Vector LIBRARYNAME = LLVMTransforms Index: llvm/lib/Transforms/TransformInternals.cpp diff -u llvm/lib/Transforms/TransformInternals.cpp:1.49 llvm/lib/Transforms/TransformInternals.cpp:1.49.2.1 --- llvm/lib/Transforms/TransformInternals.cpp:1.49 Tue Jul 26 11:38:28 2005 +++ llvm/lib/Transforms/TransformInternals.cpp Wed Nov 16 12:32:47 2005 @@ -14,7 +14,6 @@ #include "TransformInternals.h" #include "llvm/Type.h" -#include "llvm/Analysis/Expressions.h" #include "llvm/Function.h" #include "llvm/Instructions.h" using namespace llvm; From bocchino at cs.uiuc.edu Wed Nov 16 12:33:00 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:00 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Transforms/IPO/GlobalOpt.cpp LowerSetJmp.cpp Makefile SimplifyLibCalls.cpp Message-ID: <200511161833.MAA21239@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: GlobalOpt.cpp updated: 1.58.2.1 -> 1.58.2.2 LowerSetJmp.cpp updated: 1.27 -> 1.27.2.1 Makefile updated: 1.4 -> 1.4.6.1 SimplifyLibCalls.cpp updated: 1.54 -> 1.54.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+16 -11) GlobalOpt.cpp | 6 ++++-- LowerSetJmp.cpp | 15 ++++++++------- Makefile | 1 + SimplifyLibCalls.cpp | 5 +++-- 4 files changed, 16 insertions(+), 11 deletions(-) Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.58.2.1 llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.58.2.2 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.58.2.1 Tue Oct 18 14:21:57 2005 +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp Wed Nov 16 12:32:48 2005 @@ -678,7 +678,7 @@ (unsigned)NElements->getRawValue()); MallocInst *NewMI = new MallocInst(NewTy, Constant::getNullValue(Type::UIntTy), - MI->getName(), MI); + MI->getAlignment(), MI->getName(), MI); std::vector Indices; Indices.push_back(Constant::getNullValue(Type::IntTy)); Indices.push_back(Indices[0]); @@ -950,6 +950,7 @@ DEBUG(std::cerr << "LOCALIZING GLOBAL: " << *GV); Instruction* FirstI = GS.AccessingFunction->getEntryBlock().begin(); const Type* ElemTy = GV->getType()->getElementType(); + // FIXME: Pass Global's alignment when globals have alignment AllocaInst* Alloca = new AllocaInst(ElemTy, NULL, GV->getName(), FirstI); if (!isa(GV->getInitializer())) new StoreInst(GV->getInitializer(), Alloca, FirstI); @@ -1113,7 +1114,8 @@ /// FindGlobalCtors - Find the llvm.globalctors list, verifying that all /// initializers have an init priority of 65535. GlobalVariable *GlobalOpt::FindGlobalCtors(Module &M) { - for (Module::giterator I = M.global_begin(), E = M.global_end(); I != E; ++I) + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) if (I->getName() == "llvm.global_ctors") { // Found it, verify it's an array of { int, void()* }. const ArrayType *ATy =dyn_cast(I->getType()->getElementType()); Index: llvm/lib/Transforms/IPO/LowerSetJmp.cpp diff -u llvm/lib/Transforms/IPO/LowerSetJmp.cpp:1.27 llvm/lib/Transforms/IPO/LowerSetJmp.cpp:1.27.2.1 --- llvm/lib/Transforms/IPO/LowerSetJmp.cpp:1.27 Wed Jun 15 17:49:30 2005 +++ llvm/lib/Transforms/IPO/LowerSetJmp.cpp Wed Nov 16 12:32:48 2005 @@ -204,32 +204,33 @@ // void __llvm_sjljeh_init_setjmpmap(void**) InitSJMap = M.getOrInsertFunction("__llvm_sjljeh_init_setjmpmap", - Type::VoidTy, SBPPTy, NULL); + Type::VoidTy, SBPPTy, (Type *)0); // void __llvm_sjljeh_destroy_setjmpmap(void**) DestroySJMap = M.getOrInsertFunction("__llvm_sjljeh_destroy_setjmpmap", - Type::VoidTy, SBPPTy, NULL); + Type::VoidTy, SBPPTy, (Type *)0); // void __llvm_sjljeh_add_setjmp_to_map(void**, void*, unsigned) AddSJToMap = M.getOrInsertFunction("__llvm_sjljeh_add_setjmp_to_map", Type::VoidTy, SBPPTy, SBPTy, - Type::UIntTy, NULL); + Type::UIntTy, (Type *)0); // void __llvm_sjljeh_throw_longjmp(int*, int) ThrowLongJmp = M.getOrInsertFunction("__llvm_sjljeh_throw_longjmp", - Type::VoidTy, SBPTy, Type::IntTy, NULL); + Type::VoidTy, SBPTy, Type::IntTy, + (Type *)0); // unsigned __llvm_sjljeh_try_catching_longjmp_exception(void **) TryCatchLJ = M.getOrInsertFunction("__llvm_sjljeh_try_catching_longjmp_exception", - Type::UIntTy, SBPPTy, NULL); + Type::UIntTy, SBPPTy, (Type *)0); // bool __llvm_sjljeh_is_longjmp_exception() IsLJException = M.getOrInsertFunction("__llvm_sjljeh_is_longjmp_exception", - Type::BoolTy, NULL); + Type::BoolTy, (Type *)0); // int __llvm_sjljeh_get_longjmp_value() GetLJValue = M.getOrInsertFunction("__llvm_sjljeh_get_longjmp_value", - Type::IntTy, NULL); + Type::IntTy, (Type *)0); return true; } Index: llvm/lib/Transforms/IPO/Makefile diff -u llvm/lib/Transforms/IPO/Makefile:1.4 llvm/lib/Transforms/IPO/Makefile:1.4.6.1 --- llvm/lib/Transforms/IPO/Makefile:1.4 Wed Oct 27 18:18:45 2004 +++ llvm/lib/Transforms/IPO/Makefile Wed Nov 16 12:32:48 2005 @@ -6,6 +6,7 @@ # the University of Illinois Open Source License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## + LEVEL = ../../.. LIBRARYNAME = LLVMipo BUILD_ARCHIVE = 1 Index: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp diff -u llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.54 llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.54.2.1 --- llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.54 Thu Sep 29 01:17:27 2005 +++ llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp Wed Nov 16 12:32:48 2005 @@ -311,7 +311,8 @@ if (!memcpy_func) { const Type *SBP = PointerType::get(Type::SByteTy); memcpy_func = M->getOrInsertFunction("llvm.memcpy", Type::VoidTy,SBP, SBP, - Type::UIntTy, Type::UIntTy, 0); + Type::UIntTy, Type::UIntTy, + (Type *)0); } return memcpy_func; } @@ -319,7 +320,7 @@ Function* get_floorf() { if (!floorf_func) floorf_func = M->getOrInsertFunction("floorf", Type::FloatTy, - Type::FloatTy, 0); + Type::FloatTy, (Type *)0); return floorf_func; } From bocchino at cs.uiuc.edu Wed Nov 16 12:32:49 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:49 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Target/PowerPC/Makefile PPC.td PPCAsmPrinter.cpp PPCISelDAGToDAG.cpp PPCISelLowering.cpp PPCISelLowering.h PPCISelPattern.cpp PPCInstrFormats.td PPCInstrInfo.cpp PPCInstrInfo.td PPCRegisterInfo.cpp PPCRegisterInfo.td PPCSchedule.td PPCScheduleG3.td PPCScheduleG4.td PPCScheduleG4Plus.td PPCScheduleG5.td PPCSubtarget.cpp PPCSubtarget.h PPCTargetMachine.cpp PPCTargetMachine.h README.txt Message-ID: <200511161832.MAA21142@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: Makefile updated: 1.20 -> 1.20.2.1 PPC.td updated: 1.2 -> 1.2.2.1 PPCAsmPrinter.cpp updated: 1.100 -> 1.100.2.1 PPCISelDAGToDAG.cpp updated: 1.108 -> 1.108.2.1 PPCISelLowering.cpp updated: 1.33 -> 1.33.2.1 PPCISelLowering.h updated: 1.8 -> 1.8.2.1 PPCISelPattern.cpp updated: 1.190 -> 1.190.2.1 PPCInstrFormats.td updated: 1.52 -> 1.52.2.1 PPCInstrInfo.cpp updated: 1.12 -> 1.12.2.1 PPCInstrInfo.td updated: 1.124 -> 1.124.2.1 PPCRegisterInfo.cpp updated: 1.36 -> 1.36.2.1 PPCRegisterInfo.td updated: 1.18 -> 1.18.2.1 PPCSchedule.td updated: 1.1 -> 1.1.2.1 PPCScheduleG3.td updated: 1.2 -> 1.2.2.1 PPCScheduleG4.td updated: 1.2 -> 1.2.2.1 PPCScheduleG4Plus.td updated: 1.2 -> 1.2.2.1 PPCScheduleG5.td updated: 1.2 -> 1.2.2.1 PPCSubtarget.cpp updated: 1.10 -> 1.10.2.1 PPCSubtarget.h updated: 1.8 -> 1.8.2.1 PPCTargetMachine.cpp updated: 1.75 -> 1.75.2.1 PPCTargetMachine.h updated: 1.14 -> 1.14.2.1 README.txt updated: 1.33 -> 1.33.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+996 -1005) Makefile | 2 PPC.td | 43 ++++ PPCAsmPrinter.cpp | 120 +++++++----- PPCISelDAGToDAG.cpp | 427 ++++++++++++--------------------------------- PPCISelLowering.cpp | 53 ++++- PPCISelLowering.h | 3 PPCISelPattern.cpp | 154 ---------------- PPCInstrFormats.td | 255 +++++++++++++++------------ PPCInstrInfo.cpp | 3 PPCInstrInfo.td | 480 +++++++++++++++++++++++++++++---------------------- PPCRegisterInfo.cpp | 29 ++- PPCRegisterInfo.td | 34 +++ PPCSchedule.td | 124 +++++-------- PPCScheduleG3.td | 8 PPCScheduleG4.td | 8 PPCScheduleG4Plus.td | 8 PPCScheduleG5.td | 8 PPCSubtarget.cpp | 81 +------- PPCSubtarget.h | 17 + PPCTargetMachine.cpp | 10 - PPCTargetMachine.h | 15 + README.txt | 119 ++++++++++++ 22 files changed, 996 insertions(+), 1005 deletions(-) Index: llvm/lib/Target/PowerPC/Makefile diff -u llvm/lib/Target/PowerPC/Makefile:1.20 llvm/lib/Target/PowerPC/Makefile:1.20.2.1 --- llvm/lib/Target/PowerPC/Makefile:1.20 Fri Oct 14 18:37:35 2005 +++ llvm/lib/Target/PowerPC/Makefile Wed Nov 16 12:32:37 2005 @@ -14,6 +14,6 @@ BUILT_SOURCES = PPCGenInstrNames.inc PPCGenRegisterNames.inc \ PPCGenAsmWriter.inc PPCGenCodeEmitter.inc \ PPCGenRegisterInfo.h.inc PPCGenRegisterInfo.inc \ - PPCGenInstrInfo.inc PPCGenDAGISel.inc + PPCGenInstrInfo.inc PPCGenDAGISel.inc PPCGenSubtarget.inc include $(LEVEL)/Makefile.common Index: llvm/lib/Target/PowerPC/PPC.td diff -u llvm/lib/Target/PowerPC/PPC.td:1.2 llvm/lib/Target/PowerPC/PPC.td:1.2.2.1 --- llvm/lib/Target/PowerPC/PPC.td:1.2 Fri Oct 14 18:40:39 2005 +++ llvm/lib/Target/PowerPC/PPC.td Wed Nov 16 12:32:38 2005 @@ -16,12 +16,55 @@ include "../Target.td" //===----------------------------------------------------------------------===// +// PowerPC Subtarget features. +// + +def Feature64Bit : SubtargetFeature<"64bit", "bool", "Is64Bit", + "Enable 64-bit instructions">; +def Feature64BitRegs : SubtargetFeature<"64bitregs", "bool", "Has64BitRegs", + "Enable 64-bit registers [beta]">; +def FeatureAltivec : SubtargetFeature<"altivec", "bool", "HasAltivec", + "Enable Altivec instructions">; +def FeatureGPUL : SubtargetFeature<"gpul", "bool", "IsGigaProcessor", + "Enable GPUL instructions">; +def FeatureFSqrt : SubtargetFeature<"fsqrt", "bool", "HasFSQRT", + "Enable the fsqrt instruction">; + +//===----------------------------------------------------------------------===// // Register File Description //===----------------------------------------------------------------------===// include "PPCRegisterInfo.td" +include "PPCSchedule.td" include "PPCInstrInfo.td" +//===----------------------------------------------------------------------===// +// PowerPC processors supported. +// + +def : Processor<"generic", G3Itineraries, []>; +def : Processor<"601", G3Itineraries, []>; +def : Processor<"602", G3Itineraries, []>; +def : Processor<"603", G3Itineraries, []>; +def : Processor<"603e", G3Itineraries, []>; +def : Processor<"603ev", G3Itineraries, []>; +def : Processor<"604", G3Itineraries, []>; +def : Processor<"604e", G3Itineraries, []>; +def : Processor<"620", G3Itineraries, []>; +def : Processor<"g3", G3Itineraries, []>; +def : Processor<"7400", G4Itineraries, [FeatureAltivec]>; +def : Processor<"g4", G4Itineraries, [FeatureAltivec]>; +def : Processor<"7450", G4PlusItineraries, [FeatureAltivec]>; +def : Processor<"g4+", G4PlusItineraries, [FeatureAltivec]>; +def : Processor<"750", G3Itineraries, []>; +def : Processor<"970", G5Itineraries, + [FeatureAltivec, FeatureGPUL, FeatureFSqrt, + Feature64Bit /*, Feature64BitRegs */]>; +def : Processor<"g5", G5Itineraries, + [FeatureAltivec, FeatureGPUL, FeatureFSqrt, + Feature64Bit /*, Feature64BitRegs */]>; + + def PPC : Target { // Pointers on PPC are 32-bits in size. let PointerType = i32; Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.100 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.100.2.1 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.100 Tue Oct 18 11:51:22 2005 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Wed Nov 16 12:32:38 2005 @@ -43,15 +43,17 @@ namespace { Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); - struct PPCAsmPrinter : public AsmPrinter { + class PPCAsmPrinter : public AsmPrinter { + std::string CurSection; + public: std::set FnStubs, GVStubs, LinkOnceStubs; - + PPCAsmPrinter(std::ostream &O, TargetMachine &TM) - : AsmPrinter(O, TM), LabelNumber(0) {} + : AsmPrinter(O, TM), FunctionNumber(0) {} /// Unique incrementer for label values for referencing Global values. /// - unsigned LabelNumber; + unsigned FunctionNumber; virtual const char *getPassName() const { return "PowerPC Assembly Printer"; @@ -61,6 +63,24 @@ return static_cast(TM); } + /// SwitchSection - Switch to the specified section of the executable if we + /// are not already in it! + /// + void SwitchSection(const char *NewSection, const GlobalValue *GV) { + std::string NS; + + if (GV && GV->hasSection()) + NS = ".section " + GV->getSection(); + else + NS = NewSection; + + if (CurSection != NS) { + CurSection = NS; + if (!CurSection.empty()) + O << "\t" << CurSection << "\n"; + } + } + unsigned enumRegToMachineReg(unsigned enumReg) { switch (enumReg) { default: assert(0 && "Unhandled register!"); break; @@ -135,8 +155,8 @@ void printPICLabel(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT) { // FIXME: should probably be converted to cout.width and cout.fill - O << "\"L0000" << LabelNumber << "$pb\"\n"; - O << "\"L0000" << LabelNumber << "$pb\":"; + O << "\"L0000" << FunctionNumber << "$pb\"\n"; + O << "\"L0000" << FunctionNumber << "$pb\":"; } void printSymbolHi(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT) { @@ -146,7 +166,7 @@ O << "ha16("; printOp(MI->getOperand(OpNo)); if (PICEnabled) - O << "-\"L0000" << LabelNumber << "$pb\")"; + O << "-\"L0000" << FunctionNumber << "$pb\")"; else O << ')'; } @@ -159,7 +179,7 @@ O << "lo16("; printOp(MI->getOperand(OpNo)); if (PICEnabled) - O << "-\"L0000" << LabelNumber << "$pb\")"; + O << "-\"L0000" << FunctionNumber << "$pb\")"; else O << ')'; } @@ -210,7 +230,7 @@ AIXAsmPrinter(std::ostream &O, TargetMachine &TM) : PPCAsmPrinter(O, TM) { CommentString = "#"; - GlobalPrefix = "_"; + GlobalPrefix = "."; ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. Data64bitsDirective = 0; // we can't emit a 64-bit unit AlignmentIsInBytes = false; // Alignment is by power of 2. @@ -227,18 +247,6 @@ }; } // end of anonymous namespace -// SwitchSection - Switch to the specified section of the executable if we are -// not already in it! -// -static void SwitchSection(std::ostream &OS, std::string &CurSection, - const char *NewSection) { - if (CurSection != NewSection) { - CurSection = NewSection; - if (!CurSection.empty()) - OS << "\t" << NewSection << "\n"; - } -} - /// createDarwinAsmPrinterPass - Returns a pass that prints the PPC assembly /// code for a MachineFunction to the given output stream, in a format that the /// Darwin assembler can deal with. @@ -287,14 +295,13 @@ case MachineOperand::MO_MachineBasicBlock: { MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); - O << "LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) - << "_" << MBBOp->getNumber() << "\t; " + O << "LBB" << FunctionNumber << "_" << MBBOp->getNumber() << "\t; " << MBBOp->getBasicBlock()->getName(); return; } case MachineOperand::MO_ConstantPoolIndex: - O << ".CPI" << CurrentFnName << "_" << MO.getConstantPoolIndex(); + O << "LCPI" << FunctionNumber << '_' << MO.getConstantPoolIndex(); return; case MachineOperand::MO_ExternalSymbol: @@ -388,9 +395,11 @@ printConstantPool(MF.getConstantPool()); // Print out labels for the function. - O << "\t.text\n"; - emitAlignment(4); - O << "\t.globl\t" << CurrentFnName << "\n"; + const Function *F = MF.getFunction(); + SwitchSection(".text", F); + emitAlignment(4, F); + if (!F->hasInternalLinkage()) + O << "\t.globl\t" << CurrentFnName << "\n"; O << CurrentFnName << ":\n"; // Print out code for the function. @@ -398,7 +407,7 @@ I != E; ++I) { // Print a label for the basic block. if (I != MF.begin()) { - O << "LBB" << CurrentFnName << "_" << I->getNumber() << ":\t"; + O << "LBB" << FunctionNumber << '_' << I->getNumber() << ":\t"; if (!I->getBasicBlock()->getName().empty()) O << CommentString << " " << I->getBasicBlock()->getName(); O << "\n"; @@ -410,7 +419,7 @@ printMachineInstruction(II); } } - ++LabelNumber; + ++FunctionNumber; // We didn't modify anything. return false; @@ -428,15 +437,15 @@ if (CP.empty()) return; for (unsigned i = 0, e = CP.size(); i != e; ++i) { - O << "\t.const\n"; + SwitchSection(".const", 0); // FIXME: force doubles to be naturally aligned. We should handle this // more correctly in the future. if (Type::DoubleTy == CP[i]->getType()) emitAlignment(3); else emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType())); - O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString - << *CP[i] << "\n"; + O << "LCPI" << FunctionNumber << '_' << i << ":\t\t\t\t\t" << CommentString + << *CP[i] << '\n'; emitGlobalConstant(CP[i]); } } @@ -444,16 +453,20 @@ bool DarwinAsmPrinter::doInitialization(Module &M) { if (TM.getSubtarget().isGigaProcessor()) O << "\t.machine ppc970\n"; + SwitchSection("", 0); AsmPrinter::doInitialization(M); + + // Darwin wants symbols to be quoted if they have complex names. + Mang->setUseQuotes(true); return false; } bool DarwinAsmPrinter::doFinalization(Module &M) { const TargetData &TD = TM.getTargetData(); - std::string CurSection; // Print out module-level global variables here. - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) if (I->hasInitializer()) { // External global require no code O << '\n'; std::string name = Mang->getValueName(I); @@ -464,7 +477,7 @@ if (C->isNullValue() && /* FIXME: Verify correct */ (I->hasInternalLinkage() || I->hasWeakLinkage() || I->hasLinkOnceLinkage())) { - SwitchSection(O, CurSection, ".data"); + SwitchSection(".data", I); if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. if (I->hasInternalLinkage()) O << ".lcomm " << name << "," << Size << "," << Align; @@ -474,6 +487,7 @@ } else { switch (I->getLinkage()) { case GlobalValue::LinkOnceLinkage: + SwitchSection("", 0); O << ".section __TEXT,__textcoal_nt,coalesced,no_toc\n" << ".weak_definition " << name << '\n' << ".private_extern " << name << '\n' @@ -492,14 +506,14 @@ O << "\t.globl " << name << "\n"; // FALL THROUGH case GlobalValue::InternalLinkage: - SwitchSection(O, CurSection, ".data"); + SwitchSection(".data", I); break; - case GlobalValue::GhostLinkage: - std::cerr << "Error: unmaterialized (GhostLinkage) function in asm!"; + default: + std::cerr << "Unknown linkage type!"; abort(); } - emitAlignment(Align); + emitAlignment(Align, I); O << name << ":\t\t\t\t; '" << I->getName() << "'\n"; emitGlobalConstant(C); } @@ -566,6 +580,13 @@ << "\t.long\t" << *i << '\n'; } + // Funny Darwin hack: This flag tells the linker that no global symbols + // contain code that falls through to other global symbols (e.g. the obvious + // implementation of multiple entry points). If this doesn't occur, the + // linker can safely perform dead code stripping. Since LLVM never generates + // code that does this, it is always safe to set. + O << "\t.subsections_via_symbols\n"; + AsmPrinter::doFinalization(M); return false; // success } @@ -594,8 +615,8 @@ for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); I != E; ++I) { // Print a label for the basic block. - O << "LBB" << CurrentFnName << "_" << I->getNumber() << ":\t# " - << I->getBasicBlock()->getName() << "\n"; + O << "LBB" << CurrentFnName << '_' << I->getNumber() << ":\t# " + << I->getBasicBlock()->getName() << '\n'; for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); II != E; ++II) { // Print the assembly for the instruction. @@ -603,7 +624,7 @@ printMachineInstruction(II); } } - ++LabelNumber; + ++FunctionNumber; O << "LT.." << CurrentFnName << ":\n" << "\t.long 0\n" @@ -629,18 +650,18 @@ if (CP.empty()) return; for (unsigned i = 0, e = CP.size(); i != e; ++i) { - O << "\t.const\n"; + SwitchSection(".const", 0); O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType()) << "\n"; - O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t;" - << *CP[i] << "\n"; + O << "LCPI" << FunctionNumber << '_' << i << ":\t\t\t\t\t;" + << *CP[i] << '\n'; emitGlobalConstant(CP[i]); } } bool AIXAsmPrinter::doInitialization(Module &M) { + SwitchSection("", 0); const TargetData &TD = TM.getTargetData(); - std::string CurSection; O << "\t.machine \"ppc64\"\n" << "\t.toc\n" @@ -675,7 +696,7 @@ continue; std::string Name = GV->getName(); - std::string Label = "LC.." + utostr(LabelNumber++); + std::string Label = "LC.." + utostr(FunctionNumber++); GVToLabelMap[GV] = Label; O << Label << ":\n" << "\t.tc " << Name << "[TC]," << Name; @@ -683,7 +704,7 @@ O << '\n'; } - Mang = new Mangler(M, "."); + AsmPrinter::doInitialization(M); return false; // success } @@ -710,7 +731,6 @@ O << "_section_.text:\n" << "\t.csect .data[RW],3\n" << "\t.llong _section_.text\n"; - - delete Mang; + AsmPrinter::doFinalization(M); return false; // success } Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.108 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.108.2.1 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.108 Mon Oct 17 19:28:58 2005 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Wed Nov 16 12:32:38 2005 @@ -219,6 +219,11 @@ // and mask opcode and mask operation. static bool isRotateAndMask(SDNode *N, unsigned Mask, bool IsShiftMask, unsigned &SH, unsigned &MB, unsigned &ME) { + // Don't even go down this path for i64, since different logic will be + // necessary for rldicl/rldicr/rldimi. + if (N->getValueType(0) != MVT::i32) + return false; + unsigned Shift = 32; unsigned Indeterminant = ~0; // bit mask marking indeterminant results unsigned Opcode = N->getOpcode(); @@ -474,16 +479,25 @@ static unsigned getBCCForSetCC(ISD::CondCode CC) { switch (CC) { default: assert(0 && "Unknown condition!"); abort(); + case ISD::SETOEQ: // FIXME: This is incorrect see PR642. case ISD::SETEQ: return PPC::BEQ; + case ISD::SETONE: // FIXME: This is incorrect see PR642. case ISD::SETNE: return PPC::BNE; + case ISD::SETOLT: // FIXME: This is incorrect see PR642. case ISD::SETULT: case ISD::SETLT: return PPC::BLT; + case ISD::SETOLE: // FIXME: This is incorrect see PR642. case ISD::SETULE: case ISD::SETLE: return PPC::BLE; + case ISD::SETOGT: // FIXME: This is incorrect see PR642. case ISD::SETUGT: case ISD::SETGT: return PPC::BGT; + case ISD::SETOGE: // FIXME: This is incorrect see PR642. case ISD::SETUGE: case ISD::SETGE: return PPC::BGE; + + case ISD::SETO: return PPC::BUN; + case ISD::SETUO: return PPC::BNU; } return 0; } @@ -494,163 +508,28 @@ static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool& Inv) { switch (CC) { default: assert(0 && "Unknown condition!"); abort(); + case ISD::SETOLT: // FIXME: This is incorrect see PR642. case ISD::SETULT: case ISD::SETLT: Inv = false; return 0; + case ISD::SETOGE: // FIXME: This is incorrect see PR642. case ISD::SETUGE: case ISD::SETGE: Inv = true; return 0; + case ISD::SETOGT: // FIXME: This is incorrect see PR642. case ISD::SETUGT: case ISD::SETGT: Inv = false; return 1; + case ISD::SETOLE: // FIXME: This is incorrect see PR642. case ISD::SETULE: case ISD::SETLE: Inv = true; return 1; + case ISD::SETOEQ: // FIXME: This is incorrect see PR642. case ISD::SETEQ: Inv = false; return 2; + case ISD::SETONE: // FIXME: This is incorrect see PR642. case ISD::SETNE: Inv = true; return 2; + case ISD::SETO: Inv = true; return 3; + case ISD::SETUO: Inv = false; return 3; } return 0; } -// Structure used to return the necessary information to codegen an SDIV as -// a multiply. -struct ms { - int m; // magic number - int s; // shift amount -}; - -struct mu { - unsigned int m; // magic number - int a; // add indicator - int s; // shift amount -}; - -/// magic - calculate the magic numbers required to codegen an integer sdiv as -/// a sequence of multiply and shifts. Requires that the divisor not be 0, 1, -/// or -1. -static struct ms magic(int d) { - int p; - unsigned int ad, anc, delta, q1, r1, q2, r2, t; - const unsigned int two31 = 0x80000000U; - struct ms mag; - - ad = abs(d); - t = two31 + ((unsigned int)d >> 31); - anc = t - 1 - t%ad; // absolute value of nc - p = 31; // initialize p - q1 = two31/anc; // initialize q1 = 2p/abs(nc) - r1 = two31 - q1*anc; // initialize r1 = rem(2p,abs(nc)) - q2 = two31/ad; // initialize q2 = 2p/abs(d) - r2 = two31 - q2*ad; // initialize r2 = rem(2p,abs(d)) - do { - p = p + 1; - q1 = 2*q1; // update q1 = 2p/abs(nc) - r1 = 2*r1; // update r1 = rem(2p/abs(nc)) - if (r1 >= anc) { // must be unsigned comparison - q1 = q1 + 1; - r1 = r1 - anc; - } - q2 = 2*q2; // update q2 = 2p/abs(d) - r2 = 2*r2; // update r2 = rem(2p/abs(d)) - if (r2 >= ad) { // must be unsigned comparison - q2 = q2 + 1; - r2 = r2 - ad; - } - delta = ad - r2; - } while (q1 < delta || (q1 == delta && r1 == 0)); - - mag.m = q2 + 1; - if (d < 0) mag.m = -mag.m; // resulting magic number - mag.s = p - 32; // resulting shift - return mag; -} - -/// magicu - calculate the magic numbers required to codegen an integer udiv as -/// a sequence of multiply, add and shifts. Requires that the divisor not be 0. -static struct mu magicu(unsigned d) -{ - int p; - unsigned int nc, delta, q1, r1, q2, r2; - struct mu magu; - magu.a = 0; // initialize "add" indicator - nc = - 1 - (-d)%d; - p = 31; // initialize p - q1 = 0x80000000/nc; // initialize q1 = 2p/nc - r1 = 0x80000000 - q1*nc; // initialize r1 = rem(2p,nc) - q2 = 0x7FFFFFFF/d; // initialize q2 = (2p-1)/d - r2 = 0x7FFFFFFF - q2*d; // initialize r2 = rem((2p-1),d) - do { - p = p + 1; - if (r1 >= nc - r1 ) { - q1 = 2*q1 + 1; // update q1 - r1 = 2*r1 - nc; // update r1 - } - else { - q1 = 2*q1; // update q1 - r1 = 2*r1; // update r1 - } - if (r2 + 1 >= d - r2) { - if (q2 >= 0x7FFFFFFF) magu.a = 1; - q2 = 2*q2 + 1; // update q2 - r2 = 2*r2 + 1 - d; // update r2 - } - else { - if (q2 >= 0x80000000) magu.a = 1; - q2 = 2*q2; // update q2 - r2 = 2*r2 + 1; // update r2 - } - delta = d - 1 - r2; - } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0))); - magu.m = q2 + 1; // resulting magic number - magu.s = p - 32; // resulting shift - return magu; -} - -/// BuildSDIVSequence - Given an ISD::SDIV node expressing a divide by constant, -/// return a DAG expression to select that will generate the same value by -/// multiplying by a magic number. See: -/// -SDOperand PPCDAGToDAGISel::BuildSDIVSequence(SDNode *N) { - int d = (int)cast(N->getOperand(1))->getValue(); - ms magics = magic(d); - // Multiply the numerator (operand 0) by the magic value - SDOperand Q = CurDAG->getNode(ISD::MULHS, MVT::i32, N->getOperand(0), - CurDAG->getConstant(magics.m, MVT::i32)); - // If d > 0 and m < 0, add the numerator - if (d > 0 && magics.m < 0) - Q = CurDAG->getNode(ISD::ADD, MVT::i32, Q, N->getOperand(0)); - // If d < 0 and m > 0, subtract the numerator. - if (d < 0 && magics.m > 0) - Q = CurDAG->getNode(ISD::SUB, MVT::i32, Q, N->getOperand(0)); - // Shift right algebraic if shift value is nonzero - if (magics.s > 0) - Q = CurDAG->getNode(ISD::SRA, MVT::i32, Q, - CurDAG->getConstant(magics.s, MVT::i32)); - // Extract the sign bit and add it to the quotient - SDOperand T = - CurDAG->getNode(ISD::SRL, MVT::i32, Q, CurDAG->getConstant(31, MVT::i32)); - return CurDAG->getNode(ISD::ADD, MVT::i32, Q, T); -} - -/// BuildUDIVSequence - Given an ISD::UDIV node expressing a divide by constant, -/// return a DAG expression to select that will generate the same value by -/// multiplying by a magic number. See: -/// -SDOperand PPCDAGToDAGISel::BuildUDIVSequence(SDNode *N) { - unsigned d = (unsigned)cast(N->getOperand(1))->getValue(); - mu magics = magicu(d); - // Multiply the numerator (operand 0) by the magic value - SDOperand Q = CurDAG->getNode(ISD::MULHU, MVT::i32, N->getOperand(0), - CurDAG->getConstant(magics.m, MVT::i32)); - if (magics.a == 0) { - return CurDAG->getNode(ISD::SRL, MVT::i32, Q, - CurDAG->getConstant(magics.s, MVT::i32)); - } else { - SDOperand NPQ = CurDAG->getNode(ISD::SUB, MVT::i32, N->getOperand(0), Q); - NPQ = CurDAG->getNode(ISD::SRL, MVT::i32, NPQ, - CurDAG->getConstant(1, MVT::i32)); - NPQ = CurDAG->getNode(ISD::ADD, MVT::i32, NPQ, Q); - return CurDAG->getNode(ISD::SRL, MVT::i32, NPQ, - CurDAG->getConstant(magics.s-1, MVT::i32)); - } -} - SDOperand PPCDAGToDAGISel::SelectDYNAMIC_STACKALLOC(SDOperand Op) { SDNode *N = Op.Val; @@ -759,65 +638,63 @@ if (Imm == 0) { SDOperand Op = Select(N->getOperand(0)); switch (CC) { - default: assert(0 && "Unhandled SetCC condition"); abort(); - case ISD::SETEQ: - Op = CurDAG->getTargetNode(PPC::CNTLZW, MVT::i32, Op); - CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Op, getI32Imm(27), - getI32Imm(5), getI32Imm(31)); - break; - case ISD::SETNE: { - SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, - Op, getI32Imm(~0U)); - CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1)); - break; - } - case ISD::SETLT: - CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Op, getI32Imm(1), - getI32Imm(31), getI32Imm(31)); - break; - case ISD::SETGT: { - SDOperand T = CurDAG->getTargetNode(PPC::NEG, MVT::i32, Op); - T = CurDAG->getTargetNode(PPC::ANDC, MVT::i32, T, Op);; - CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, T, getI32Imm(1), - getI32Imm(31), getI32Imm(31)); - break; - } + default: break; + case ISD::SETEQ: + Op = CurDAG->getTargetNode(PPC::CNTLZW, MVT::i32, Op); + CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Op, getI32Imm(27), + getI32Imm(5), getI32Imm(31)); + return SDOperand(N, 0); + case ISD::SETNE: { + SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, + Op, getI32Imm(~0U)); + CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1)); + return SDOperand(N, 0); + } + case ISD::SETLT: + CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Op, getI32Imm(1), + getI32Imm(31), getI32Imm(31)); + return SDOperand(N, 0); + case ISD::SETGT: { + SDOperand T = CurDAG->getTargetNode(PPC::NEG, MVT::i32, Op); + T = CurDAG->getTargetNode(PPC::ANDC, MVT::i32, T, Op);; + CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, T, getI32Imm(1), + getI32Imm(31), getI32Imm(31)); + return SDOperand(N, 0); + } } - return SDOperand(N, 0); } else if (Imm == ~0U) { // setcc op, -1 SDOperand Op = Select(N->getOperand(0)); switch (CC) { - default: assert(0 && "Unhandled SetCC condition"); abort(); - case ISD::SETEQ: - Op = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, - Op, getI32Imm(1)); - CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32, - CurDAG->getTargetNode(PPC::LI, MVT::i32, - getI32Imm(0)), - Op.getValue(1)); - break; - case ISD::SETNE: { - Op = CurDAG->getTargetNode(PPC::NOR, MVT::i32, Op, Op); - SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, - Op, getI32Imm(~0U)); - CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1)); - break; - } - case ISD::SETLT: { - SDOperand AD = CurDAG->getTargetNode(PPC::ADDI, MVT::i32, Op, - getI32Imm(1)); - SDOperand AN = CurDAG->getTargetNode(PPC::AND, MVT::i32, AD, Op); - CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, AN, getI32Imm(1), - getI32Imm(31), getI32Imm(31)); - break; - } - case ISD::SETGT: - Op = CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, Op, getI32Imm(1), - getI32Imm(31), getI32Imm(31)); - CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Op, getI32Imm(1)); - break; + default: break; + case ISD::SETEQ: + Op = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, + Op, getI32Imm(1)); + CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32, + CurDAG->getTargetNode(PPC::LI, MVT::i32, + getI32Imm(0)), + Op.getValue(1)); + return SDOperand(N, 0); + case ISD::SETNE: { + Op = CurDAG->getTargetNode(PPC::NOR, MVT::i32, Op, Op); + SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, + Op, getI32Imm(~0U)); + CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1)); + return SDOperand(N, 0); + } + case ISD::SETLT: { + SDOperand AD = CurDAG->getTargetNode(PPC::ADDI, MVT::i32, Op, + getI32Imm(1)); + SDOperand AN = CurDAG->getTargetNode(PPC::AND, MVT::i32, AD, Op); + CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, AN, getI32Imm(1), + getI32Imm(31), getI32Imm(31)); + return SDOperand(N, 0); + } + case ISD::SETGT: + Op = CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, Op, getI32Imm(1), + getI32Imm(31), getI32Imm(31)); + CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Op, getI32Imm(1)); + return SDOperand(N, 0); } - return SDOperand(N, 0); } } @@ -845,11 +722,13 @@ if (!Inv) { CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, IntCR, - getI32Imm(32-(3-Idx)), getI32Imm(31), getI32Imm(31)); + getI32Imm((32-(3-Idx)) & 31), + getI32Imm(31), getI32Imm(31)); } else { SDOperand Tmp = CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, IntCR, - getI32Imm(32-(3-Idx)), getI32Imm(31),getI32Imm(31)); + getI32Imm((32-(3-Idx)) & 31), + getI32Imm(31),getI32Imm(31)); CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Tmp, getI32Imm(1)); } @@ -984,52 +863,17 @@ case ISD::CALL: return SelectCALL(Op); case ISD::TAILCALL: return SelectCALL(Op); - case ISD::TokenFactor: { - SDOperand New; - if (N->getNumOperands() == 2) { - SDOperand Op0 = Select(N->getOperand(0)); - SDOperand Op1 = Select(N->getOperand(1)); - New = CurDAG->getNode(ISD::TokenFactor, MVT::Other, Op0, Op1); - } else { - std::vector Ops; - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) - Ops.push_back(Select(N->getOperand(i))); - New = CurDAG->getNode(ISD::TokenFactor, MVT::Other, Ops); - } - - CodeGenMap[Op] = New; - return New; - } - case ISD::CopyFromReg: { - SDOperand Chain = Select(N->getOperand(0)); - if (Chain == N->getOperand(0)) return Op; // No change - SDOperand New = CurDAG->getCopyFromReg(Chain, - cast(N->getOperand(1))->getReg(), N->getValueType(0)); - return New.getValue(Op.ResNo); - } - case ISD::CopyToReg: { - SDOperand Chain = Select(N->getOperand(0)); - SDOperand Reg = N->getOperand(1); - SDOperand Val = Select(N->getOperand(2)); - SDOperand New = CurDAG->getNode(ISD::CopyToReg, MVT::Other, - Chain, Reg, Val); - CodeGenMap[Op] = New; - return New; - } - case ISD::UNDEF: - if (N->getValueType(0) == MVT::i32) - CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_GPR, MVT::i32); - else if (N->getValueType(0) == MVT::f32) - CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F4, MVT::f32); - else - CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F8, MVT::f64); - return SDOperand(N, 0); case ISD::FrameIndex: { int FI = cast(N)->getIndex(); - CurDAG->SelectNodeTo(N, PPC::ADDI, MVT::i32, - CurDAG->getTargetFrameIndex(FI, MVT::i32), - getI32Imm(0)); - return SDOperand(N, 0); + if (N->hasOneUse()) { + CurDAG->SelectNodeTo(N, PPC::ADDI, MVT::i32, + CurDAG->getTargetFrameIndex(FI, MVT::i32), + getI32Imm(0)); + return SDOperand(N, 0); + } + return CurDAG->getTargetNode(PPC::ADDI, MVT::i32, + CurDAG->getTargetFrameIndex(FI, MVT::i32), + getI32Imm(0)); } case ISD::ConstantPool: { Constant *C = cast(N)->get(); @@ -1038,8 +882,11 @@ Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(),CPI); else Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, CPI); - CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, CPI); - return SDOperand(N, 0); + if (N->hasOneUse()) { + CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, CPI); + return SDOperand(N, 0); + } + return CurDAG->getTargetNode(PPC::LA, MVT::i32, Tmp, CPI); } case ISD::GlobalAddress: { GlobalValue *GV = cast(N)->getGlobal(); @@ -1051,35 +898,10 @@ Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, GA); if (GV->hasWeakLinkage() || GV->isExternal()) - CurDAG->SelectNodeTo(N, PPC::LWZ, MVT::i32, GA, Tmp); + return CurDAG->getTargetNode(PPC::LWZ, MVT::i32, GA, Tmp); else - CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, GA); - return SDOperand(N, 0); + return CurDAG->getTargetNode(PPC::LA, MVT::i32, Tmp, GA); } - - case PPCISD::FSEL: { - SDOperand Comparison = Select(N->getOperand(0)); - // Extend the comparison to 64-bits. - if (Comparison.getValueType() == MVT::f32) - Comparison = CurDAG->getTargetNode(PPC::FMRSD, MVT::f64, Comparison); - - unsigned Opc = N->getValueType(0) == MVT::f32 ? PPC::FSELS : PPC::FSELD; - CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Comparison, - Select(N->getOperand(1)), Select(N->getOperand(2))); - return SDOperand(N, 0); - } - case PPCISD::FCFID: - CurDAG->SelectNodeTo(N, PPC::FCFID, N->getValueType(0), - Select(N->getOperand(0))); - return SDOperand(N, 0); - case PPCISD::FCTIDZ: - CurDAG->SelectNodeTo(N, PPC::FCTIDZ, N->getValueType(0), - Select(N->getOperand(0))); - return SDOperand(N, 0); - case PPCISD::FCTIWZ: - CurDAG->SelectNodeTo(N, PPC::FCTIWZ, N->getValueType(0), - Select(N->getOperand(0))); - return SDOperand(N, 0); case ISD::FADD: { MVT::ValueType Ty = N->getValueType(0); if (!NoExcessFPPrecision) { // Match FMA ops @@ -1134,6 +956,11 @@ return SDOperand(N, 0); } case ISD::SDIV: { + // FIXME: since this depends on the setting of the carry flag from the srawi + // we should really be making notes about that for the scheduler. + // FIXME: It sure would be nice if we could cheaply recognize the + // srl/add/sra pattern the dag combiner will generate for this as + // sra/addze rather than having to handle sdiv ourselves. oh well. unsigned Imm; if (isIntImmediate(N->getOperand(1), Imm)) { if ((signed)Imm > 0 && isPowerOf2_32(Imm)) { @@ -1154,29 +981,12 @@ Op.getValue(1)); CurDAG->SelectNodeTo(N, PPC::NEG, MVT::i32, PT); return SDOperand(N, 0); - } else if (Imm) { - SDOperand Result = Select(BuildSDIVSequence(N)); - CodeGenMap[Op] = Result; - return Result; } } // Other cases are autogenerated. break; } - case ISD::UDIV: { - // If this is a divide by constant, we can emit code using some magic - // constants to implement it as a multiply instead. - unsigned Imm; - if (isIntImmediate(N->getOperand(1), Imm) && Imm) { - SDOperand Result = Select(BuildUDIVSequence(N)); - CodeGenMap[Op] = Result; - return Result; - } - - // Other cases are autogenerated. - break; - } case ISD::AND: { unsigned Imm; // If this is an and of a value rotated between 0 and 31 bits and then and'd @@ -1187,7 +997,10 @@ unsigned SH, MB, ME; if (isRotateAndMask(N->getOperand(0).Val, Imm, false, SH, MB, ME)) { Val = Select(N->getOperand(0).getOperand(0)); - } else { + } else if (Imm == 0) { + // AND X, 0 -> 0, not "rlwinm 32". + return Select(N->getOperand(1)); + } else { Val = Select(N->getOperand(0)); isRunOfOnes(Imm, MB, ME); SH = 0; @@ -1209,33 +1022,28 @@ case ISD::SHL: { unsigned Imm, SH, MB, ME; if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) && - isRotateAndMask(N, Imm, true, SH, MB, ME)) + isRotateAndMask(N, Imm, true, SH, MB, ME)) { CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0).getOperand(0)), getI32Imm(SH), getI32Imm(MB), getI32Imm(ME)); - else if (isIntImmediate(N->getOperand(1), Imm)) - CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0)), - getI32Imm(Imm), getI32Imm(0), getI32Imm(31-Imm)); - else - CurDAG->SelectNodeTo(N, PPC::SLW, MVT::i32, Select(N->getOperand(0)), - Select(N->getOperand(1))); - return SDOperand(N, 0); + return SDOperand(N, 0); + } + + // Other cases are autogenerated. + break; } case ISD::SRL: { unsigned Imm, SH, MB, ME; if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) && - isRotateAndMask(N, Imm, true, SH, MB, ME)) + isRotateAndMask(N, Imm, true, SH, MB, ME)) { CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0).getOperand(0)), getI32Imm(SH & 0x1F), getI32Imm(MB), getI32Imm(ME)); - else if (isIntImmediate(N->getOperand(1), Imm)) - CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0)), - getI32Imm((32-Imm) & 0x1F), getI32Imm(Imm), - getI32Imm(31)); - else - CurDAG->SelectNodeTo(N, PPC::SRW, MVT::i32, Select(N->getOperand(0)), - Select(N->getOperand(1))); - return SDOperand(N, 0); + return SDOperand(N, 0); + } + + // Other cases are autogenerated. + break; } case ISD::FNEG: { SDOperand Val = Select(N->getOperand(0)); @@ -1393,11 +1201,6 @@ SDOperand Val = Select(N->getOperand(1)); if (N->getOperand(1).getValueType() == MVT::i32) { Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Val); - } else if (N->getOperand(1).getValueType() == MVT::i64) { - SDOperand Srl = CurDAG->getTargetNode(PPC::RLDICL, MVT::i64, Val, - getI32Imm(32), getI32Imm(32)); - Chain = CurDAG->getCopyToReg(Chain, PPC::R4, Val); - Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Srl); } else { assert(MVT::isFloatingPoint(N->getOperand(1).getValueType())); Chain = CurDAG->getCopyToReg(Chain, PPC::F1, Val); Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.33 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.33.2.1 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.33 Mon Oct 17 19:56:42 2005 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Wed Nov 16 12:32:38 2005 @@ -27,6 +27,7 @@ // Fold away setcc operations if possible. setSetCCIsExpensive(); + setPow2DivIsCheap(); // Use _setjmp/_longjmp instead of setjmp/longjmp. setUseUnderscoreSetJmpLongJmp(true); @@ -80,9 +81,6 @@ setOperationAction(ISD::BRCOND, MVT::Other, Expand); setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand); - // PowerPC does not have FP_TO_UINT - setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); - // PowerPC turns FP_TO_SINT into FCTIWZ and some load/stores. setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); @@ -97,6 +95,11 @@ // They also have instructions for converting between i64 and fp. setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom); + // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT + setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote); + } else { + // PowerPC does not have FP_TO_UINT on 32 bit implementations. + setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); } if (TM.getSubtarget().has64BitRegs()) { @@ -203,34 +206,47 @@ std::swap(TV, FV); // fsel is natively setge, swap operands for setlt case ISD::SETUGE: case ISD::SETGE: + if (LHS.getValueType() == MVT::f32) // Comparison is always 64-bits + LHS = DAG.getNode(ISD::FP_EXTEND, MVT::f64, LHS); return DAG.getNode(PPCISD::FSEL, ResVT, LHS, TV, FV); case ISD::SETUGT: case ISD::SETGT: std::swap(TV, FV); // fsel is natively setge, swap operands for setlt case ISD::SETULE: case ISD::SETLE: + if (LHS.getValueType() == MVT::f32) // Comparison is always 64-bits + LHS = DAG.getNode(ISD::FP_EXTEND, MVT::f64, LHS); return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::FNEG, ResVT, LHS), TV, FV); + DAG.getNode(ISD::FNEG, MVT::f64, LHS), TV, FV); } + SDOperand Cmp; switch (CC) { default: assert(0 && "Invalid FSEL condition"); abort(); case ISD::SETULT: case ISD::SETLT: - return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS), FV, TV); + Cmp = DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS); + if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits + Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); + return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, FV, TV); case ISD::SETUGE: case ISD::SETGE: - return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS), TV, FV); + Cmp = DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS); + if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits + Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); + return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, TV, FV); case ISD::SETUGT: case ISD::SETGT: - return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS), FV, TV); + Cmp = DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS); + if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits + Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); + return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, FV, TV); case ISD::SETULE: case ISD::SETLE: - return DAG.getNode(PPCISD::FSEL, ResVT, - DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS), TV, FV); + Cmp = DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS); + if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits + Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); + return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, TV, FV); } break; } @@ -693,6 +709,19 @@ return std::make_pair(RetVal, Chain); } +SDOperand PPCTargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, + SelectionDAG &DAG) { + if (Op.getValueType() == MVT::i64) { + SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, + DAG.getConstant(1, MVT::i32)); + SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, + DAG.getConstant(0, MVT::i32)); + return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Hi); + } else { + return DAG.getNode(ISD::RET, MVT::Other, Chain, Op); + } +} + SDOperand PPCTargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, Value *VAListV, SelectionDAG &DAG) { // vastart just stores the address of the VarArgsFrameIndex slot into the Index: llvm/lib/Target/PowerPC/PPCISelLowering.h diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.8 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.8.2.1 --- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.8 Sun Oct 16 00:39:50 2005 +++ llvm/lib/Target/PowerPC/PPCISelLowering.h Wed Nov 16 12:32:38 2005 @@ -63,6 +63,9 @@ unsigned CC, bool isTailCall, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); + + virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op, + SelectionDAG &DAG); virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, Value *VAListV, SelectionDAG &DAG); Index: llvm/lib/Target/PowerPC/PPCISelPattern.cpp diff -u llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.190 llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.190.2.1 --- llvm/lib/Target/PowerPC/PPCISelPattern.cpp:1.190 Mon Oct 17 19:28:58 2005 +++ llvm/lib/Target/PowerPC/PPCISelPattern.cpp Wed Nov 16 12:32:38 2005 @@ -274,151 +274,6 @@ } return 0; } - -// Structure used to return the necessary information to codegen an SDIV as -// a multiply. -struct ms { - int m; // magic number - int s; // shift amount -}; - -struct mu { - unsigned int m; // magic number - int a; // add indicator - int s; // shift amount -}; - -/// magic - calculate the magic numbers required to codegen an integer sdiv as -/// a sequence of multiply and shifts. Requires that the divisor not be 0, 1, -/// or -1. -static struct ms magic(int d) { - int p; - unsigned int ad, anc, delta, q1, r1, q2, r2, t; - const unsigned int two31 = 0x80000000U; - struct ms mag; - - ad = abs(d); - t = two31 + ((unsigned int)d >> 31); - anc = t - 1 - t%ad; // absolute value of nc - p = 31; // initialize p - q1 = two31/anc; // initialize q1 = 2p/abs(nc) - r1 = two31 - q1*anc; // initialize r1 = rem(2p,abs(nc)) - q2 = two31/ad; // initialize q2 = 2p/abs(d) - r2 = two31 - q2*ad; // initialize r2 = rem(2p,abs(d)) - do { - p = p + 1; - q1 = 2*q1; // update q1 = 2p/abs(nc) - r1 = 2*r1; // update r1 = rem(2p/abs(nc)) - if (r1 >= anc) { // must be unsigned comparison - q1 = q1 + 1; - r1 = r1 - anc; - } - q2 = 2*q2; // update q2 = 2p/abs(d) - r2 = 2*r2; // update r2 = rem(2p/abs(d)) - if (r2 >= ad) { // must be unsigned comparison - q2 = q2 + 1; - r2 = r2 - ad; - } - delta = ad - r2; - } while (q1 < delta || (q1 == delta && r1 == 0)); - - mag.m = q2 + 1; - if (d < 0) mag.m = -mag.m; // resulting magic number - mag.s = p - 32; // resulting shift - return mag; -} - -/// magicu - calculate the magic numbers required to codegen an integer udiv as -/// a sequence of multiply, add and shifts. Requires that the divisor not be 0. -static struct mu magicu(unsigned d) -{ - int p; - unsigned int nc, delta, q1, r1, q2, r2; - struct mu magu; - magu.a = 0; // initialize "add" indicator - nc = - 1 - (-d)%d; - p = 31; // initialize p - q1 = 0x80000000/nc; // initialize q1 = 2p/nc - r1 = 0x80000000 - q1*nc; // initialize r1 = rem(2p,nc) - q2 = 0x7FFFFFFF/d; // initialize q2 = (2p-1)/d - r2 = 0x7FFFFFFF - q2*d; // initialize r2 = rem((2p-1),d) - do { - p = p + 1; - if (r1 >= nc - r1 ) { - q1 = 2*q1 + 1; // update q1 - r1 = 2*r1 - nc; // update r1 - } - else { - q1 = 2*q1; // update q1 - r1 = 2*r1; // update r1 - } - if (r2 + 1 >= d - r2) { - if (q2 >= 0x7FFFFFFF) magu.a = 1; - q2 = 2*q2 + 1; // update q2 - r2 = 2*r2 + 1 - d; // update r2 - } - else { - if (q2 >= 0x80000000) magu.a = 1; - q2 = 2*q2; // update q2 - r2 = 2*r2 + 1; // update r2 - } - delta = d - 1 - r2; - } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0))); - magu.m = q2 + 1; // resulting magic number - magu.s = p - 32; // resulting shift - return magu; -} -} - -/// BuildSDIVSequence - Given an ISD::SDIV node expressing a divide by constant, -/// return a DAG expression to select that will generate the same value by -/// multiplying by a magic number. See: -/// -SDOperand ISel::BuildSDIVSequence(SDOperand N) { - int d = (int)cast(N.getOperand(1))->getSignExtended(); - ms magics = magic(d); - // Multiply the numerator (operand 0) by the magic value - SDOperand Q = ISelDAG->getNode(ISD::MULHS, MVT::i32, N.getOperand(0), - ISelDAG->getConstant(magics.m, MVT::i32)); - // If d > 0 and m < 0, add the numerator - if (d > 0 && magics.m < 0) - Q = ISelDAG->getNode(ISD::ADD, MVT::i32, Q, N.getOperand(0)); - // If d < 0 and m > 0, subtract the numerator. - if (d < 0 && magics.m > 0) - Q = ISelDAG->getNode(ISD::SUB, MVT::i32, Q, N.getOperand(0)); - // Shift right algebraic if shift value is nonzero - if (magics.s > 0) - Q = ISelDAG->getNode(ISD::SRA, MVT::i32, Q, - ISelDAG->getConstant(magics.s, MVT::i32)); - // Extract the sign bit and add it to the quotient - SDOperand T = - ISelDAG->getNode(ISD::SRL, MVT::i32, Q, ISelDAG->getConstant(31, MVT::i32)); - return ISelDAG->getNode(ISD::ADD, MVT::i32, Q, T); -} - -/// BuildUDIVSequence - Given an ISD::UDIV node expressing a divide by constant, -/// return a DAG expression to select that will generate the same value by -/// multiplying by a magic number. See: -/// -SDOperand ISel::BuildUDIVSequence(SDOperand N) { - unsigned d = - (unsigned)cast(N.getOperand(1))->getSignExtended(); - mu magics = magicu(d); - // Multiply the numerator (operand 0) by the magic value - SDOperand Q = ISelDAG->getNode(ISD::MULHU, MVT::i32, N.getOperand(0), - ISelDAG->getConstant(magics.m, MVT::i32)); - if (magics.a == 0) { - Q = ISelDAG->getNode(ISD::SRL, MVT::i32, Q, - ISelDAG->getConstant(magics.s, MVT::i32)); - } else { - SDOperand NPQ = ISelDAG->getNode(ISD::SUB, MVT::i32, N.getOperand(0), Q); - NPQ = ISelDAG->getNode(ISD::SRL, MVT::i32, NPQ, - ISelDAG->getConstant(1, MVT::i32)); - NPQ = ISelDAG->getNode(ISD::ADD, MVT::i32, NPQ, Q); - Q = ISelDAG->getNode(ISD::SRL, MVT::i32, NPQ, - ISelDAG->getConstant(magics.s-1, MVT::i32)); - } - return Q; } /// getGlobalBaseReg - Output the instructions required to put the @@ -1395,19 +1250,10 @@ BuildMI(BB, PPC::ADDZE, 1, Tmp4).addReg(Tmp1); BuildMI(BB, PPC::NEG, 1, Result).addReg(Tmp4); return Result; - } else if (Tmp3) { - ExprMap.erase(N); - return SelectExpr(BuildSDIVSequence(N)); } } // fall thru case ISD::UDIV: - // If this is a divide by constant, we can emit code using some magic - // constants to implement it as a multiply instead. - if (isIntImmediate(N.getOperand(1), Tmp3) && Tmp3) { - ExprMap.erase(N); - return SelectExpr(BuildUDIVSequence(N)); - } Tmp1 = SelectExpr(N.getOperand(0)); Tmp2 = SelectExpr(N.getOperand(1)); Opc = (ISD::UDIV == opcode) ? PPC::DIVWU : PPC::DIVW; break; Index: llvm/lib/Target/PowerPC/PPCInstrFormats.td diff -u llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.52 llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.52.2.1 --- llvm/lib/Target/PowerPC/PPCInstrFormats.td:1.52 Fri Oct 14 17:44:13 2005 +++ llvm/lib/Target/PowerPC/PPCInstrFormats.td Wed Nov 16 12:32:38 2005 @@ -14,7 +14,8 @@ // // PowerPC instruction formats -class I opcode, dag OL, string asmstr> : Instruction { +class I opcode, dag OL, string asmstr, InstrItinClass itin> + : Instruction { field bits<32> Inst; bit PPC64 = 0; // Default value, override with isPPC64 @@ -25,11 +26,13 @@ let Inst{0-5} = opcode; let OperandList = OL; let AsmString = asmstr; + let Itinerary = itin; } // 1.7.1 I-Form -class IForm opcode, bit aa, bit lk, dag OL, string asmstr> - : I { +class IForm opcode, bit aa, bit lk, dag OL, string asmstr, + InstrItinClass itin> + : I { bits<24> LI; let Inst{6-29} = LI; @@ -39,8 +42,8 @@ // 1.7.2 B-Form class BForm opcode, bit aa, bit lk, bits<5> bo, bits<2> bicode, dag OL, - string asmstr> - : I { + string asmstr, InstrItinClass itin> + : I { bits<3> CR; bits<14> BD; @@ -53,8 +56,9 @@ } // 1.7.4 D-Form -class DForm_base opcode, dag OL, string asmstr, list pattern> - : I { +class DForm_base opcode, dag OL, string asmstr, InstrItinClass itin, + list pattern> + : I { let Pattern = pattern; bits<5> A; bits<5> B; @@ -65,8 +69,8 @@ let Inst{16-31} = C; } -class DForm_1 opcode, dag OL, string asmstr> - : I { +class DForm_1 opcode, dag OL, string asmstr, InstrItinClass itin> + : I { bits<5> A; bits<16> C; bits<5> B; @@ -76,11 +80,13 @@ let Inst{16-31} = C; } -class DForm_2 opcode, dag OL, string asmstr, list pattern> - : DForm_base; +class DForm_2 opcode, dag OL, string asmstr, InstrItinClass itin, + list pattern> + : DForm_base; -class DForm_2_r0 opcode, dag OL, string asmstr, list pattern> - : I { +class DForm_2_r0 opcode, dag OL, string asmstr, InstrItinClass itin, + list pattern> + : I { bits<5> A; bits<16> B; @@ -92,11 +98,12 @@ } // Currently we make the use/def reg distinction in ISel, not tablegen -class DForm_3 opcode, dag OL, string asmstr> - : DForm_1; +class DForm_3 opcode, dag OL, string asmstr, InstrItinClass itin> + : DForm_1; -class DForm_4 opcode, dag OL, string asmstr, list pattern> - : I { +class DForm_4 opcode, dag OL, string asmstr, InstrItinClass itin, + list pattern> + : I { bits<5> B; bits<5> A; bits<16> C; @@ -108,14 +115,15 @@ let Inst{16-31} = C; } -class DForm_4_zero opcode, dag OL, string asmstr> - : DForm_1 { +class DForm_4_zero opcode, dag OL, string asmstr, InstrItinClass itin> + : DForm_1 { let A = 0; let B = 0; let C = 0; } -class DForm_5 opcode, dag OL, string asmstr> : I { +class DForm_5 opcode, dag OL, string asmstr, InstrItinClass itin> + : I { bits<3> BF; bits<1> L; bits<5> RA; @@ -128,30 +136,31 @@ let Inst{16-31} = I; } -class DForm_5_ext opcode, dag OL, string asmstr> - : DForm_5 { +class DForm_5_ext opcode, dag OL, string asmstr, InstrItinClass itin> + : DForm_5 { let L = PPC64; } -class DForm_6 opcode, dag OL, string asmstr> - : DForm_5; +class DForm_6 opcode, dag OL, string asmstr, InstrItinClass itin> + : DForm_5; -class DForm_6_ext opcode, dag OL, string asmstr> - : DForm_6 { +class DForm_6_ext opcode, dag OL, string asmstr, InstrItinClass itin> + : DForm_6 { let L = PPC64; } -class DForm_8 opcode, dag OL, string asmstr> - : DForm_1 { +class DForm_8 opcode, dag OL, string asmstr, InstrItinClass itin> + : DForm_1 { } -class DForm_9 opcode, dag OL, string asmstr> - : DForm_1 { +class DForm_9 opcode, dag OL, string asmstr, InstrItinClass itin> + : DForm_1 { } // 1.7.5 DS-Form -class DSForm_1 opcode, bits<2> xo, dag OL, string asmstr> - : I { +class DSForm_1 opcode, bits<2> xo, dag OL, string asmstr, + InstrItinClass itin> + : I { bits<5> RST; bits<14> DS; bits<5> RA; @@ -162,12 +171,14 @@ let Inst{30-31} = xo; } -class DSForm_2 opcode, bits<2> xo, dag OL, string asmstr> - : DSForm_1; +class DSForm_2 opcode, bits<2> xo, dag OL, string asmstr, + InstrItinClass itin> + : DSForm_1; // 1.7.6 X-Form class XForm_base_r3xo opcode, bits<10> xo, - dag OL, string asmstr> : I { + dag OL, string asmstr, InstrItinClass itin> + : I { bits<5> RST; bits<5> A; bits<5> B; @@ -184,8 +195,9 @@ // This is the same as XForm_base_r3xo, but the first two operands are swapped // when code is emitted. class XForm_base_r3xo_swapped - opcode, bits<10> xo, dag OL, string asmstr> - : I { + opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin> + : I { bits<5> A; bits<5> RST; bits<5> B; @@ -200,32 +212,36 @@ } -class XForm_1 opcode, bits<10> xo, dag OL, string asmstr> - : XForm_base_r3xo; - -class XForm_6 opcode, bits<10> xo, dag OL, string asmstr, - list pattern> - : XForm_base_r3xo_swapped { +class XForm_1 opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin> + : XForm_base_r3xo; + +class XForm_6 opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin, list pattern> + : XForm_base_r3xo_swapped { let Pattern = pattern; } -class XForm_8 opcode, bits<10> xo, dag OL, string asmstr> - : XForm_base_r3xo; - -class XForm_10 opcode, bits<10> xo, dag OL, string asmstr, list pt> - : XForm_base_r3xo_swapped { - let Pattern = pt; +class XForm_8 opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin> + : XForm_base_r3xo; + +class XForm_10 opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin, list pattern> + : XForm_base_r3xo_swapped { + let Pattern = pattern; } class XForm_11 opcode, bits<10> xo, dag OL, string asmstr, - list pattern> - : XForm_base_r3xo_swapped { + InstrItinClass itin, list pattern> + : XForm_base_r3xo_swapped { let B = 0; let Pattern = pattern; } -class XForm_16 opcode, bits<10> xo, dag OL, string asmstr> - : I { +class XForm_16 opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin> + : I { bits<3> BF; bits<1> L; bits<5> RA; @@ -240,13 +256,15 @@ let Inst{31} = 0; } -class XForm_16_ext opcode, bits<10> xo, dag OL, string asmstr> - : XForm_16 { +class XForm_16_ext opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin> + : XForm_16 { let L = PPC64; } -class XForm_17 opcode, bits<10> xo, dag OL, string asmstr> - : I { +class XForm_17 opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin> + : I { bits<3> BF; bits<5> FRA; bits<5> FRB; @@ -259,23 +277,27 @@ let Inst{31} = 0; } -class XForm_25 opcode, bits<10> xo, dag OL, string asmstr> - : XForm_base_r3xo { +class XForm_25 opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin> + : XForm_base_r3xo { } -class XForm_26 opcode, bits<10> xo, dag OL, string asmstr, list pt> - : XForm_base_r3xo { +class XForm_26 opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin, list pattern> + : XForm_base_r3xo { let A = 0; - let Pattern = pt; + let Pattern = pattern; } -class XForm_28 opcode, bits<10> xo, dag OL, string asmstr> - : XForm_base_r3xo { +class XForm_28 opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin> + : XForm_base_r3xo { } // 1.7.7 XL-Form -class XLForm_1 opcode, bits<10> xo, dag OL, string asmstr> - : I { +class XLForm_1 opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin> + : I { bits<3> CRD; bits<2> CRDb; bits<3> CRA; @@ -293,8 +315,9 @@ let Inst{31} = 0; } -class XLForm_2 opcode, bits<10> xo, bit lk, - dag OL, string asmstr> : I { +class XLForm_2 opcode, bits<10> xo, bit lk, dag OL, string asmstr, + InstrItinClass itin> + : I { bits<5> BO; bits<5> BI; bits<2> BH; @@ -307,16 +330,17 @@ let Inst{31} = lk; } -class XLForm_2_ext opcode, bits<10> xo, bits<5> bo, - bits<5> bi, bit lk, dag OL, string asmstr> - : XLForm_2 { +class XLForm_2_ext opcode, bits<10> xo, bits<5> bo, bits<5> bi, bit lk, + dag OL, string asmstr, InstrItinClass itin> + : XLForm_2 { let BO = bo; let BI = bi; let BH = 0; } -class XLForm_3 opcode, bits<10> xo, dag OL, string asmstr> - : I { +class XLForm_3 opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin> + : I { bits<3> BF; bits<3> BFA; @@ -330,8 +354,9 @@ } // 1.7.8 XFX-Form -class XFXForm_1 opcode, bits<10> xo, dag OL, string asmstr> - : I { +class XFXForm_1 opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin> + : I { bits<5> RT; bits<10> SPR; @@ -342,13 +367,14 @@ } class XFXForm_1_ext opcode, bits<10> xo, bits<10> spr, - dag OL, string asmstr> - : XFXForm_1 { + dag OL, string asmstr, InstrItinClass itin> + : XFXForm_1 { let SPR = spr; } -class XFXForm_3 opcode, bits<10> xo, dag OL, string asmstr> - : I { +class XFXForm_3 opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin> + : I { bits<5> RT; let Inst{6-10} = RT; @@ -357,8 +383,9 @@ let Inst{31} = 0; } -class XFXForm_5 opcode, bits<10> xo, dag OL, string asmstr> - : I { +class XFXForm_5 opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin> + : I { bits<8> FXM; bits<5> ST; @@ -370,8 +397,9 @@ let Inst{31} = 0; } -class XFXForm_5a opcode, bits<10> xo, dag OL, string asmstr> - : I { +class XFXForm_5a opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin> + : I { bits<5> ST; bits<8> FXM; @@ -384,18 +412,20 @@ } -class XFXForm_7 opcode, bits<10> xo, dag OL, string asmstr> - : XFXForm_1; +class XFXForm_7 opcode, bits<10> xo, dag OL, string asmstr, + InstrItinClass itin> + : XFXForm_1; class XFXForm_7_ext opcode, bits<10> xo, bits<10> spr, - dag OL, string asmstr> - : XFXForm_7 { + dag OL, string asmstr, InstrItinClass itin> + : XFXForm_7 { let SPR = spr; } // 1.7.10 XS-Form -class XSForm_1 opcode, bits<9> xo, dag OL, string asmstr> - : I { +class XSForm_1 opcode, bits<9> xo, dag OL, string asmstr, + InstrItinClass itin> + : I { bits<5> RS; bits<5> A; bits<6> SH; @@ -412,8 +442,8 @@ // 1.7.11 XO-Form class XOForm_1 opcode, bits<9> xo, bit oe, dag OL, string asmstr, - list pattern> - : I { + InstrItinClass itin, list pattern> + : I { bits<5> RT; bits<5> RA; bits<5> RB; @@ -431,15 +461,15 @@ } class XOForm_3 opcode, bits<9> xo, bit oe, - dag OL, string asmstr, list pattern> - : XOForm_1 { + dag OL, string asmstr, InstrItinClass itin, list pattern> + : XOForm_1 { let RB = 0; } // 1.7.12 A-Form class AForm_1 opcode, bits<5> xo, dag OL, string asmstr, - list pattern> - : I { + InstrItinClass itin, list pattern> + : I { bits<5> FRT; bits<5> FRA; bits<5> FRC; @@ -457,24 +487,30 @@ let Inst{31} = RC; } -class AForm_2 opcode, bits<5> xo, dag OL, string asmstr, list pat> - : AForm_1 { +class AForm_2 opcode, bits<5> xo, dag OL, string asmstr, + InstrItinClass itin, list pattern> + : AForm_1 { let FRC = 0; } -class AForm_3 opcode, bits<5> xo, dag OL, string asmstr, list pat> - : AForm_1 { +class AForm_3 opcode, bits<5> xo, dag OL, string asmstr, + InstrItinClass itin, list pattern> + : AForm_1 { let FRB = 0; } // 1.7.13 M-Form -class MForm_1 opcode, dag OL, string asmstr> : I { +class MForm_1 opcode, dag OL, string asmstr, + InstrItinClass itin, list pattern> + : I { bits<5> RA; bits<5> RS; bits<5> RB; bits<5> MB; bits<5> ME; + let Pattern = pattern; + bit RC = 0; // set by isDOT let Inst{6-10} = RS; @@ -485,18 +521,22 @@ let Inst{31} = RC; } -class MForm_2 opcode, dag OL, string asmstr> - : MForm_1 { +class MForm_2 opcode, dag OL, string asmstr, + InstrItinClass itin, list pattern> + : MForm_1 { } // 1.7.14 MD-Form -class MDForm_1 opcode, bits<3> xo, dag OL, string asmstr> - : I { +class MDForm_1 opcode, bits<3> xo, dag OL, string asmstr, + InstrItinClass itin, list pattern> + : I { bits<5> RS; bits<5> RA; bits<6> SH; bits<6> MBE; + let Pattern = pattern; + bit RC = 0; // set by isDOT let Inst{6-10} = RS; @@ -509,10 +549,11 @@ } //===----------------------------------------------------------------------===// - -class Pseudo : I<0, OL, asmstr> { +def NoItin : InstrItinClass; +class Pseudo pattern> + : I<0, OL, asmstr, NoItin> { let PPC64 = 0; let VMX = 0; - + let Pattern = pattern; let Inst{31-0} = 0; } Index: llvm/lib/Target/PowerPC/PPCInstrInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.12 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.12.2.1 --- llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.12 Mon Oct 17 19:28:58 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.cpp Wed Nov 16 12:32:38 2005 @@ -25,7 +25,8 @@ unsigned& sourceReg, unsigned& destReg) const { MachineOpCode oc = MI.getOpcode(); - if (oc == PPC::OR4 || oc == PPC::OR8) { // or r1, r2, r2 + if (oc == PPC::OR4 || oc == PPC::OR8 || + oc == PPC::OR4To8 || oc == PPC::OR8To4) { // or r1, r2, r2 assert(MI.getNumOperands() == 3 && MI.getOperand(0).isRegister() && MI.getOperand(1).isRegister() && Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.124 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.124.2.1 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.124 Tue Oct 18 11:51:22 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Wed Nov 16 12:32:38 2005 @@ -14,10 +14,43 @@ include "PPCInstrFormats.td" +//===----------------------------------------------------------------------===// +// PowerPC specific DAG Nodes. +// + +def PPCfcfid : SDNode<"PPCISD::FCFID" , SDTFPUnaryOp, []>; +def PPCfctidz : SDNode<"PPCISD::FCTIDZ", SDTFPUnaryOp, []>; +def PPCfctiwz : SDNode<"PPCISD::FCTIWZ", SDTFPUnaryOp, []>; + +def PPCfsel : SDNode<"PPCISD::FSEL", + // Type constraint for fsel. + SDTypeProfile<1, 3, [SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, + SDTCisFP<0>, SDTCisVT<1, f64>]>, []>; //===----------------------------------------------------------------------===// // PowerPC specific transformation functions and pattern fragments. // + +def SHL32 : SDNodeXFormgetValue()); +}]>; + +def SHL64 : SDNodeXFormgetValue()); +}]>; + +def SRL32 : SDNodeXFormgetValue() ? getI32Imm(32 - N->getValue()) : getI32Imm(0); +}]>; + +def SRL64 : SDNodeXFormgetValue() ? getI32Imm(64 - N->getValue()) : getI32Imm(0); +}]>; + def LO16 : SDNodeXFormgetValue()); @@ -114,60 +147,67 @@ // PowerPC Instruction Definitions. // Pseudo-instructions: -def PHI : Pseudo<(ops variable_ops), "; PHI">; +def PHI : Pseudo<(ops variable_ops), "; PHI", []>; let isLoad = 1 in { -def ADJCALLSTACKDOWN : Pseudo<(ops u16imm:$amt), "; ADJCALLSTACKDOWN">; -def ADJCALLSTACKUP : Pseudo<(ops u16imm:$amt), "; ADJCALLSTACKUP">; +def ADJCALLSTACKDOWN : Pseudo<(ops u16imm:$amt), "; ADJCALLSTACKDOWN", []>; +def ADJCALLSTACKUP : Pseudo<(ops u16imm:$amt), "; ADJCALLSTACKUP", []>; } -def IMPLICIT_DEF_GPR : Pseudo<(ops GPRC:$rD), "; $rD = IMPLICIT_DEF_GPRC">; -def IMPLICIT_DEF_F8 : Pseudo<(ops F8RC:$rD), "; %rD = IMPLICIT_DEF_F8">; -def IMPLICIT_DEF_F4 : Pseudo<(ops F4RC:$rD), "; %rD = IMPLICIT_DEF_F4">; +def IMPLICIT_DEF_GPR : Pseudo<(ops GPRC:$rD), "; $rD = IMPLICIT_DEF_GPRC", + [(set GPRC:$rD, (undef))]>; +def IMPLICIT_DEF_F8 : Pseudo<(ops F8RC:$rD), "; %rD = IMPLICIT_DEF_F8", + [(set F8RC:$rD, (undef))]>; +def IMPLICIT_DEF_F4 : Pseudo<(ops F4RC:$rD), "; %rD = IMPLICIT_DEF_F4", + [(set F4RC:$rD, (undef))]>; // SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded by the // scheduler into a branch sequence. let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. def SELECT_CC_Int : Pseudo<(ops GPRC:$dst, CRRC:$cond, GPRC:$T, GPRC:$F, - i32imm:$BROPC), "; SELECT_CC PSEUDO!">; + i32imm:$BROPC), "; SELECT_CC PSEUDO!", []>; def SELECT_CC_F4 : Pseudo<(ops F4RC:$dst, CRRC:$cond, F4RC:$T, F4RC:$F, - i32imm:$BROPC), "; SELECT_CC PSEUDO!">; + i32imm:$BROPC), "; SELECT_CC PSEUDO!", []>; def SELECT_CC_F8 : Pseudo<(ops F8RC:$dst, CRRC:$cond, F8RC:$T, F8RC:$F, - i32imm:$BROPC), "; SELECT_CC PSEUDO!">; + i32imm:$BROPC), "; SELECT_CC PSEUDO!", []>; } let isTerminator = 1 in { let isReturn = 1 in - def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr">; - def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (ops), "bctr">; + def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr", BrB>; + def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (ops), "bctr", BrB>; } let Defs = [LR] in - def MovePCtoLR : Pseudo<(ops piclabel:$label), "bl $label">; + def MovePCtoLR : Pseudo<(ops piclabel:$label), "bl $label", []>; let isBranch = 1, isTerminator = 1 in { def COND_BRANCH : Pseudo<(ops CRRC:$crS, u16imm:$opc, target:$true, target:$false), - "; COND_BRANCH">; - def B : IForm<18, 0, 0, (ops target:$func), "b $func">; -//def BA : IForm<18, 1, 0, (ops target:$func), "ba $func">; - def BL : IForm<18, 0, 1, (ops target:$func), "bl $func">; -//def BLA : IForm<18, 1, 1, (ops target:$func), "bla $func">; + "; COND_BRANCH", []>; + def B : IForm<18, 0, 0, (ops target:$func), "b $func", BrB>; +//def BA : IForm<18, 1, 0, (ops target:$func), "ba $func", BrB>; + def BL : IForm<18, 0, 1, (ops target:$func), "bl $func", BrB>; +//def BLA : IForm<18, 1, 1, (ops target:$func), "bla $func", BrB>; // FIXME: 4*CR# needs to be added to the BI field! // This will only work for CR0 as it stands now def BLT : BForm<16, 0, 0, 12, 0, (ops CRRC:$crS, target:$block), - "blt $crS, $block">; + "blt $crS, $block", BrB>; def BLE : BForm<16, 0, 0, 4, 1, (ops CRRC:$crS, target:$block), - "ble $crS, $block">; + "ble $crS, $block", BrB>; def BEQ : BForm<16, 0, 0, 12, 2, (ops CRRC:$crS, target:$block), - "beq $crS, $block">; + "beq $crS, $block", BrB>; def BGE : BForm<16, 0, 0, 4, 0, (ops CRRC:$crS, target:$block), - "bge $crS, $block">; + "bge $crS, $block", BrB>; def BGT : BForm<16, 0, 0, 12, 1, (ops CRRC:$crS, target:$block), - "bgt $crS, $block">; + "bgt $crS, $block", BrB>; def BNE : BForm<16, 0, 0, 4, 2, (ops CRRC:$crS, target:$block), - "bne $crS, $block">; + "bne $crS, $block", BrB>; + def BUN : BForm<16, 0, 0, 12, 3, (ops CRRC:$crS, target:$block), + "bun $crS, $block", BrB>; + def BNU : BForm<16, 0, 0, 4, 3, (ops CRRC:$crS, target:$block), + "bnu $crS, $block", BrB>; } let isCall = 1, @@ -177,9 +217,10 @@ LR,CTR, CR0,CR1,CR5,CR6,CR7] in { // Convenient aliases for call instructions - def CALLpcrel : IForm<18, 0, 1, (ops target:$func, variable_ops), "bl $func">; + def CALLpcrel : IForm<18, 0, 1, (ops target:$func, variable_ops), + "bl $func", BrB>; def CALLindirect : XLForm_2_ext<19, 528, 20, 0, 1, - (ops variable_ops), "bctrl">; + (ops variable_ops), "bctrl", BrB>; } // D-Form instructions. Most instructions that perform an operation on a @@ -187,114 +228,114 @@ // let isLoad = 1 in { def LBZ : DForm_1<34, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), - "lbz $rD, $disp($rA)">; + "lbz $rD, $disp($rA)", LdStGeneral>; def LHA : DForm_1<42, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), - "lha $rD, $disp($rA)">; + "lha $rD, $disp($rA)", LdStLHA>; def LHZ : DForm_1<40, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), - "lhz $rD, $disp($rA)">; + "lhz $rD, $disp($rA)", LdStGeneral>; def LMW : DForm_1<46, (ops GPRC:$rD, s16imm:$disp, GPRC:$rA), - "lmw $rD, $disp($rA)">; + "lmw $rD, $disp($rA)", LdStLMW>; def LWZ : DForm_1<32, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), - "lwz $rD, $disp($rA)">; + "lwz $rD, $disp($rA)", LdStGeneral>; def LWZU : DForm_1<35, (ops GPRC:$rD, s16imm:$disp, GPRC:$rA), - "lwzu $rD, $disp($rA)">; + "lwzu $rD, $disp($rA)", LdStGeneral>; } def ADDI : DForm_2<14, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), - "addi $rD, $rA, $imm", + "addi $rD, $rA, $imm", IntGeneral, [(set GPRC:$rD, (add GPRC:$rA, immSExt16:$imm))]>; def ADDIC : DForm_2<12, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), - "addic $rD, $rA, $imm", + "addic $rD, $rA, $imm", IntGeneral, []>; def ADDICo : DForm_2<13, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), - "addic. $rD, $rA, $imm", + "addic. $rD, $rA, $imm", IntGeneral, []>; def ADDIS : DForm_2<15, (ops GPRC:$rD, GPRC:$rA, symbolHi:$imm), - "addis $rD, $rA, $imm", + "addis $rD, $rA, $imm", IntGeneral, [(set GPRC:$rD, (add GPRC:$rA, imm16Shifted:$imm))]>; def LA : DForm_2<14, (ops GPRC:$rD, GPRC:$rA, symbolLo:$sym), - "la $rD, $sym($rA)", + "la $rD, $sym($rA)", IntGeneral, []>; def MULLI : DForm_2< 7, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), - "mulli $rD, $rA, $imm", + "mulli $rD, $rA, $imm", IntMulLI, [(set GPRC:$rD, (mul GPRC:$rA, immSExt16:$imm))]>; def SUBFIC : DForm_2< 8, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), - "subfic $rD, $rA, $imm", + "subfic $rD, $rA, $imm", IntGeneral, [(set GPRC:$rD, (sub immSExt16:$imm, GPRC:$rA))]>; def LI : DForm_2_r0<14, (ops GPRC:$rD, s16imm:$imm), - "li $rD, $imm", + "li $rD, $imm", IntGeneral, [(set GPRC:$rD, immSExt16:$imm)]>; def LIS : DForm_2_r0<15, (ops GPRC:$rD, symbolHi:$imm), - "lis $rD, $imm", + "lis $rD, $imm", IntGeneral, [(set GPRC:$rD, imm16Shifted:$imm)]>; let isStore = 1 in { def STMW : DForm_3<47, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA), - "stmw $rS, $disp($rA)">; + "stmw $rS, $disp($rA)", LdStLMW>; def STB : DForm_3<38, (ops GPRC:$rS, symbolLo:$disp, GPRC:$rA), - "stb $rS, $disp($rA)">; + "stb $rS, $disp($rA)", LdStGeneral>; def STH : DForm_3<44, (ops GPRC:$rS, symbolLo:$disp, GPRC:$rA), - "sth $rS, $disp($rA)">; + "sth $rS, $disp($rA)", LdStGeneral>; def STW : DForm_3<36, (ops GPRC:$rS, symbolLo:$disp, GPRC:$rA), - "stw $rS, $disp($rA)">; + "stw $rS, $disp($rA)", LdStGeneral>; def STWU : DForm_3<37, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA), - "stwu $rS, $disp($rA)">; + "stwu $rS, $disp($rA)", LdStGeneral>; } def ANDIo : DForm_4<28, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2), - "andi. $dst, $src1, $src2", + "andi. $dst, $src1, $src2", IntGeneral, []>, isDOT; def ANDISo : DForm_4<29, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2), - "andis. $dst, $src1, $src2", + "andis. $dst, $src1, $src2", IntGeneral, []>, isDOT; def ORI : DForm_4<24, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2), - "ori $dst, $src1, $src2", + "ori $dst, $src1, $src2", IntGeneral, [(set GPRC:$dst, (or GPRC:$src1, immZExt16:$src2))]>; def ORIS : DForm_4<25, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2), - "oris $dst, $src1, $src2", + "oris $dst, $src1, $src2", IntGeneral, [(set GPRC:$dst, (or GPRC:$src1, imm16Shifted:$src2))]>; def XORI : DForm_4<26, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2), - "xori $dst, $src1, $src2", + "xori $dst, $src1, $src2", IntGeneral, [(set GPRC:$dst, (xor GPRC:$src1, immZExt16:$src2))]>; def XORIS : DForm_4<27, (ops GPRC:$dst, GPRC:$src1, u16imm:$src2), - "xoris $dst, $src1, $src2", + "xoris $dst, $src1, $src2", IntGeneral, [(set GPRC:$dst, (xor GPRC:$src1, imm16Shifted:$src2))]>; -def NOP : DForm_4_zero<24, (ops), "nop">; +def NOP : DForm_4_zero<24, (ops), "nop", IntGeneral>; def CMPI : DForm_5<11, (ops CRRC:$crD, i1imm:$L, GPRC:$rA, s16imm:$imm), - "cmpi $crD, $L, $rA, $imm">; + "cmpi $crD, $L, $rA, $imm", IntCompare>; def CMPWI : DForm_5_ext<11, (ops CRRC:$crD, GPRC:$rA, s16imm:$imm), - "cmpwi $crD, $rA, $imm">; + "cmpwi $crD, $rA, $imm", IntCompare>; def CMPDI : DForm_5_ext<11, (ops CRRC:$crD, GPRC:$rA, s16imm:$imm), - "cmpdi $crD, $rA, $imm">, isPPC64; + "cmpdi $crD, $rA, $imm", IntCompare>, isPPC64; def CMPLI : DForm_6<10, (ops CRRC:$dst, i1imm:$size, GPRC:$src1, u16imm:$src2), - "cmpli $dst, $size, $src1, $src2">; + "cmpli $dst, $size, $src1, $src2", IntCompare>; def CMPLWI : DForm_6_ext<10, (ops CRRC:$dst, GPRC:$src1, u16imm:$src2), - "cmplwi $dst, $src1, $src2">; + "cmplwi $dst, $src1, $src2", IntCompare>; def CMPLDI : DForm_6_ext<10, (ops CRRC:$dst, GPRC:$src1, u16imm:$src2), - "cmpldi $dst, $src1, $src2">, isPPC64; + "cmpldi $dst, $src1, $src2", IntCompare>, isPPC64; let isLoad = 1 in { def LFS : DForm_8<48, (ops F4RC:$rD, symbolLo:$disp, GPRC:$rA), - "lfs $rD, $disp($rA)">; + "lfs $rD, $disp($rA)", LdStLFDU>; def LFD : DForm_8<50, (ops F8RC:$rD, symbolLo:$disp, GPRC:$rA), - "lfd $rD, $disp($rA)">; + "lfd $rD, $disp($rA)", LdStLFD>; } let isStore = 1 in { def STFS : DForm_9<52, (ops F4RC:$rS, symbolLo:$disp, GPRC:$rA), - "stfs $rS, $disp($rA)">; + "stfs $rS, $disp($rA)", LdStUX>; def STFD : DForm_9<54, (ops F8RC:$rS, symbolLo:$disp, GPRC:$rA), - "stfd $rS, $disp($rA)">; + "stfd $rS, $disp($rA)", LdStUX>; } // DS-Form instructions. Load/Store instructions available in PPC-64 // let isLoad = 1 in { def LWA : DSForm_1<58, 2, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA), - "lwa $rT, $DS($rA)">, isPPC64; + "lwa $rT, $DS($rA)", LdStLWA>, isPPC64; def LD : DSForm_2<58, 0, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA), - "ld $rT, $DS($rA)">, isPPC64; + "ld $rT, $DS($rA)", LdStLD>, isPPC64; } let isStore = 1 in { def STD : DSForm_2<62, 0, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA), - "std $rT, $DS($rA)">, isPPC64; + "std $rT, $DS($rA)", LdStSTD>, isPPC64; def STDU : DSForm_2<62, 1, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA), - "stdu $rT, $DS($rA)">, isPPC64; + "stdu $rT, $DS($rA)", LdStSTD>, isPPC64; } // X-Form instructions. Most instructions that perform an operation on a @@ -302,264 +343,276 @@ // let isLoad = 1 in { def LBZX : XForm_1<31, 87, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "lbzx $dst, $base, $index">; + "lbzx $dst, $base, $index", LdStGeneral>; def LHAX : XForm_1<31, 343, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "lhax $dst, $base, $index">; + "lhax $dst, $base, $index", LdStLHA>; def LHZX : XForm_1<31, 279, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "lhzx $dst, $base, $index">; + "lhzx $dst, $base, $index", LdStGeneral>; def LWAX : XForm_1<31, 341, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "lwax $dst, $base, $index">, isPPC64; + "lwax $dst, $base, $index", LdStLHA>, isPPC64; def LWZX : XForm_1<31, 23, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "lwzx $dst, $base, $index">; + "lwzx $dst, $base, $index", LdStGeneral>; def LDX : XForm_1<31, 21, (ops GPRC:$dst, GPRC:$base, GPRC:$index), - "ldx $dst, $base, $index">, isPPC64; + "ldx $dst, $base, $index", LdStLD>, isPPC64; } def NAND : XForm_6<31, 476, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "nand $rA, $rS, $rB", + "nand $rA, $rS, $rB", IntGeneral, [(set GPRC:$rA, (not (and GPRC:$rS, GPRC:$rB)))]>; def AND : XForm_6<31, 28, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "and $rA, $rS, $rB", + "and $rA, $rS, $rB", IntGeneral, [(set GPRC:$rA, (and GPRC:$rS, GPRC:$rB))]>; def ANDo : XForm_6<31, 28, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "and. $rA, $rS, $rB", + "and. $rA, $rS, $rB", IntGeneral, []>, isDOT; def ANDC : XForm_6<31, 60, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "andc $rA, $rS, $rB", + "andc $rA, $rS, $rB", IntGeneral, [(set GPRC:$rA, (and GPRC:$rS, (not GPRC:$rB)))]>; def OR4 : XForm_6<31, 444, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "or $rA, $rS, $rB", + "or $rA, $rS, $rB", IntGeneral, [(set GPRC:$rA, (or GPRC:$rS, GPRC:$rB))]>; def OR8 : XForm_6<31, 444, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB), - "or $rA, $rS, $rB", + "or $rA, $rS, $rB", IntGeneral, [(set G8RC:$rA, (or G8RC:$rS, G8RC:$rB))]>; +def OR4To8 : XForm_6<31, 444, (ops G8RC:$rA, GPRC:$rS, GPRC:$rB), + "or $rA, $rS, $rB", IntGeneral, + []>; +def OR8To4 : XForm_6<31, 444, (ops GPRC:$rA, G8RC:$rS, G8RC:$rB), + "or $rA, $rS, $rB", IntGeneral, + []>; def NOR : XForm_6<31, 124, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "nor $rA, $rS, $rB", + "nor $rA, $rS, $rB", IntGeneral, [(set GPRC:$rA, (not (or GPRC:$rS, GPRC:$rB)))]>; def ORo : XForm_6<31, 444, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "or. $rA, $rS, $rB", + "or. $rA, $rS, $rB", IntGeneral, []>, isDOT; def ORC : XForm_6<31, 412, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "orc $rA, $rS, $rB", + "orc $rA, $rS, $rB", IntGeneral, [(set GPRC:$rA, (or GPRC:$rS, (not GPRC:$rB)))]>; def EQV : XForm_6<31, 284, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "eqv $rA, $rS, $rB", + "eqv $rA, $rS, $rB", IntGeneral, [(set GPRC:$rA, (not (xor GPRC:$rS, GPRC:$rB)))]>; def XOR : XForm_6<31, 316, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "xor $rA, $rS, $rB", + "xor $rA, $rS, $rB", IntGeneral, [(set GPRC:$rA, (xor GPRC:$rS, GPRC:$rB))]>; -def SLD : XForm_6<31, 27, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "sld $rA, $rS, $rB", - []>, isPPC64; +def SLD : XForm_6<31, 27, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB), + "sld $rA, $rS, $rB", IntRotateD, + [(set G8RC:$rA, (shl G8RC:$rS, G8RC:$rB))]>, isPPC64; def SLW : XForm_6<31, 24, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "slw $rA, $rS, $rB", + "slw $rA, $rS, $rB", IntGeneral, [(set GPRC:$rA, (shl GPRC:$rS, GPRC:$rB))]>; -def SRD : XForm_6<31, 539, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "srd $rA, $rS, $rB", - []>, isPPC64; +def SRD : XForm_6<31, 539, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB), + "srd $rA, $rS, $rB", IntRotateD, + [(set G8RC:$rA, (srl G8RC:$rS, G8RC:$rB))]>, isPPC64; def SRW : XForm_6<31, 536, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "srw $rA, $rS, $rB", + "srw $rA, $rS, $rB", IntGeneral, [(set GPRC:$rA, (srl GPRC:$rS, GPRC:$rB))]>; -def SRAD : XForm_6<31, 794, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "srad $rA, $rS, $rB", - []>, isPPC64; +def SRAD : XForm_6<31, 794, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB), + "srad $rA, $rS, $rB", IntRotateD, + [(set G8RC:$rA, (sra G8RC:$rS, G8RC:$rB))]>, isPPC64; def SRAW : XForm_6<31, 792, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB), - "sraw $rA, $rS, $rB", + "sraw $rA, $rS, $rB", IntShift, [(set GPRC:$rA, (sra GPRC:$rS, GPRC:$rB))]>; let isStore = 1 in { def STBX : XForm_8<31, 215, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), - "stbx $rS, $rA, $rB">; + "stbx $rS, $rA, $rB", LdStGeneral>; def STHX : XForm_8<31, 407, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), - "sthx $rS, $rA, $rB">; + "sthx $rS, $rA, $rB", LdStGeneral>; def STWX : XForm_8<31, 151, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), - "stwx $rS, $rA, $rB">; + "stwx $rS, $rA, $rB", LdStGeneral>; def STWUX : XForm_8<31, 183, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), - "stwux $rS, $rA, $rB">; + "stwux $rS, $rA, $rB", LdStGeneral>; def STDX : XForm_8<31, 149, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), - "stdx $rS, $rA, $rB">, isPPC64; + "stdx $rS, $rA, $rB", LdStSTD>, isPPC64; def STDUX : XForm_8<31, 181, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB), - "stdux $rS, $rA, $rB">, isPPC64; + "stdux $rS, $rA, $rB", LdStSTD>, isPPC64; } def SRAWI : XForm_10<31, 824, (ops GPRC:$rA, GPRC:$rS, u5imm:$SH), - "srawi $rA, $rS, $SH", + "srawi $rA, $rS, $SH", IntShift, [(set GPRC:$rA, (sra GPRC:$rS, imm:$SH))]>; def CNTLZW : XForm_11<31, 26, (ops GPRC:$rA, GPRC:$rS), - "cntlzw $rA, $rS", + "cntlzw $rA, $rS", IntGeneral, [(set GPRC:$rA, (ctlz GPRC:$rS))]>; def EXTSB : XForm_11<31, 954, (ops GPRC:$rA, GPRC:$rS), - "extsb $rA, $rS", + "extsb $rA, $rS", IntGeneral, [(set GPRC:$rA, (sext_inreg GPRC:$rS, i8))]>; def EXTSH : XForm_11<31, 922, (ops GPRC:$rA, GPRC:$rS), - "extsh $rA, $rS", + "extsh $rA, $rS", IntGeneral, [(set GPRC:$rA, (sext_inreg GPRC:$rS, i16))]>; def EXTSW : XForm_11<31, 986, (ops GPRC:$rA, GPRC:$rS), - "extsw $rA, $rS", + "extsw $rA, $rS", IntRotateD, []>, isPPC64; def CMP : XForm_16<31, 0, (ops CRRC:$crD, i1imm:$long, GPRC:$rA, GPRC:$rB), - "cmp $crD, $long, $rA, $rB">; + "cmp $crD, $long, $rA, $rB", IntCompare>; def CMPL : XForm_16<31, 32, (ops CRRC:$crD, i1imm:$long, GPRC:$rA, GPRC:$rB), - "cmpl $crD, $long, $rA, $rB">; + "cmpl $crD, $long, $rA, $rB", IntCompare>; def CMPW : XForm_16_ext<31, 0, (ops CRRC:$crD, GPRC:$rA, GPRC:$rB), - "cmpw $crD, $rA, $rB">; + "cmpw $crD, $rA, $rB", IntCompare>; def CMPD : XForm_16_ext<31, 0, (ops CRRC:$crD, GPRC:$rA, GPRC:$rB), - "cmpd $crD, $rA, $rB">, isPPC64; + "cmpd $crD, $rA, $rB", IntCompare>, isPPC64; def CMPLW : XForm_16_ext<31, 32, (ops CRRC:$crD, GPRC:$rA, GPRC:$rB), - "cmplw $crD, $rA, $rB">; + "cmplw $crD, $rA, $rB", IntCompare>; def CMPLD : XForm_16_ext<31, 32, (ops CRRC:$crD, GPRC:$rA, GPRC:$rB), - "cmpld $crD, $rA, $rB">, isPPC64; + "cmpld $crD, $rA, $rB", IntCompare>, isPPC64; //def FCMPO : XForm_17<63, 32, (ops CRRC:$crD, FPRC:$fA, FPRC:$fB), -// "fcmpo $crD, $fA, $fB">; +// "fcmpo $crD, $fA, $fB", FPCompare>; def FCMPUS : XForm_17<63, 0, (ops CRRC:$crD, F4RC:$fA, F4RC:$fB), - "fcmpu $crD, $fA, $fB">; + "fcmpu $crD, $fA, $fB", FPCompare>; def FCMPUD : XForm_17<63, 0, (ops CRRC:$crD, F8RC:$fA, F8RC:$fB), - "fcmpu $crD, $fA, $fB">; + "fcmpu $crD, $fA, $fB", FPCompare>; let isLoad = 1 in { def LFSX : XForm_25<31, 535, (ops F4RC:$dst, GPRC:$base, GPRC:$index), - "lfsx $dst, $base, $index">; + "lfsx $dst, $base, $index", LdStLFDU>; def LFDX : XForm_25<31, 599, (ops F8RC:$dst, GPRC:$base, GPRC:$index), - "lfdx $dst, $base, $index">; + "lfdx $dst, $base, $index", LdStLFDU>; } def FCFID : XForm_26<63, 846, (ops F8RC:$frD, F8RC:$frB), - "fcfid $frD, $frB", - []>, isPPC64; + "fcfid $frD, $frB", FPGeneral, + [(set F8RC:$frD, (PPCfcfid F8RC:$frB))]>, isPPC64; def FCTIDZ : XForm_26<63, 815, (ops F8RC:$frD, F8RC:$frB), - "fctidz $frD, $frB", - []>, isPPC64; + "fctidz $frD, $frB", FPGeneral, + [(set F8RC:$frD, (PPCfctidz F8RC:$frB))]>, isPPC64; def FCTIWZ : XForm_26<63, 15, (ops F8RC:$frD, F8RC:$frB), - "fctiwz $frD, $frB", - []>; + "fctiwz $frD, $frB", FPGeneral, + [(set F8RC:$frD, (PPCfctiwz F8RC:$frB))]>; def FRSP : XForm_26<63, 12, (ops F4RC:$frD, F8RC:$frB), - "frsp $frD, $frB", + "frsp $frD, $frB", FPGeneral, [(set F4RC:$frD, (fround F8RC:$frB))]>; def FSQRT : XForm_26<63, 22, (ops F8RC:$frD, F8RC:$frB), - "fsqrt $frD, $frB", + "fsqrt $frD, $frB", FPSqrt, [(set F8RC:$frD, (fsqrt F8RC:$frB))]>; def FSQRTS : XForm_26<59, 22, (ops F4RC:$frD, F4RC:$frB), - "fsqrts $frD, $frB", + "fsqrts $frD, $frB", FPSqrt, [(set F4RC:$frD, (fsqrt F4RC:$frB))]>; /// FMR is split into 3 versions, one for 4/8 byte FP, and one for extending. def FMRS : XForm_26<63, 72, (ops F4RC:$frD, F4RC:$frB), - "fmr $frD, $frB", + "fmr $frD, $frB", FPGeneral, []>; // (set F4RC:$frD, F4RC:$frB) def FMRD : XForm_26<63, 72, (ops F8RC:$frD, F8RC:$frB), - "fmr $frD, $frB", + "fmr $frD, $frB", FPGeneral, []>; // (set F8RC:$frD, F8RC:$frB) def FMRSD : XForm_26<63, 72, (ops F8RC:$frD, F4RC:$frB), - "fmr $frD, $frB", + "fmr $frD, $frB", FPGeneral, [(set F8RC:$frD, (fextend F4RC:$frB))]>; // These are artificially split into two different forms, for 4/8 byte FP. def FABSS : XForm_26<63, 264, (ops F4RC:$frD, F4RC:$frB), - "fabs $frD, $frB", + "fabs $frD, $frB", FPGeneral, [(set F4RC:$frD, (fabs F4RC:$frB))]>; def FABSD : XForm_26<63, 264, (ops F8RC:$frD, F8RC:$frB), - "fabs $frD, $frB", + "fabs $frD, $frB", FPGeneral, [(set F8RC:$frD, (fabs F8RC:$frB))]>; def FNABSS : XForm_26<63, 136, (ops F4RC:$frD, F4RC:$frB), - "fnabs $frD, $frB", + "fnabs $frD, $frB", FPGeneral, [(set F4RC:$frD, (fneg (fabs F4RC:$frB)))]>; def FNABSD : XForm_26<63, 136, (ops F8RC:$frD, F8RC:$frB), - "fnabs $frD, $frB", + "fnabs $frD, $frB", FPGeneral, [(set F8RC:$frD, (fneg (fabs F8RC:$frB)))]>; def FNEGS : XForm_26<63, 40, (ops F4RC:$frD, F4RC:$frB), - "fneg $frD, $frB", + "fneg $frD, $frB", FPGeneral, [(set F4RC:$frD, (fneg F4RC:$frB))]>; def FNEGD : XForm_26<63, 40, (ops F8RC:$frD, F8RC:$frB), - "fneg $frD, $frB", + "fneg $frD, $frB", FPGeneral, [(set F8RC:$frD, (fneg F8RC:$frB))]>; let isStore = 1 in { def STFSX : XForm_28<31, 663, (ops F4RC:$frS, GPRC:$rA, GPRC:$rB), - "stfsx $frS, $rA, $rB">; + "stfsx $frS, $rA, $rB", LdStUX>; def STFDX : XForm_28<31, 727, (ops F8RC:$frS, GPRC:$rA, GPRC:$rB), - "stfdx $frS, $rA, $rB">; + "stfdx $frS, $rA, $rB", LdStUX>; } // XL-Form instructions. condition register logical ops. // def MCRF : XLForm_3<19, 0, (ops CRRC:$BF, CRRC:$BFA), - "mcrf $BF, $BFA">; + "mcrf $BF, $BFA", BrMCR>; // XFX-Form instructions. Instructions that deal with SPRs // // Note that although LR should be listed as `8' and CTR as `9' in the SPR // field, the manual lists the groups of bits as [5-9] = 0, [0-4] = 8 or 9 // which means the SPR value needs to be multiplied by a factor of 32. -def MFCTR : XFXForm_1_ext<31, 339, 288, (ops GPRC:$rT), "mfctr $rT">; -def MFLR : XFXForm_1_ext<31, 339, 256, (ops GPRC:$rT), "mflr $rT">; -def MFCR : XFXForm_3<31, 19, (ops GPRC:$rT), "mfcr $rT">; +def MFCTR : XFXForm_1_ext<31, 339, 288, (ops GPRC:$rT), "mfctr $rT", SprMFSPR>; +def MFLR : XFXForm_1_ext<31, 339, 256, (ops GPRC:$rT), "mflr $rT", SprMFSPR>; +def MFCR : XFXForm_3<31, 19, (ops GPRC:$rT), "mfcr $rT", SprMFCR>; def MTCRF : XFXForm_5<31, 144, (ops crbitm:$FXM, GPRC:$rS), - "mtcrf $FXM, $rS">; + "mtcrf $FXM, $rS", BrMCRX>; def MFOCRF : XFXForm_5a<31, 19, (ops GPRC:$rT, crbitm:$FXM), - "mfcr $rT, $FXM">; -def MTCTR : XFXForm_7_ext<31, 467, 288, (ops GPRC:$rS), "mtctr $rS">; -def MTLR : XFXForm_7_ext<31, 467, 256, (ops GPRC:$rS), "mtlr $rS">; + "mfcr $rT, $FXM", SprMFCR>; +def MTCTR : XFXForm_7_ext<31, 467, 288, (ops GPRC:$rS), "mtctr $rS", SprMTSPR>; +def MTLR : XFXForm_7_ext<31, 467, 256, (ops GPRC:$rS), "mtlr $rS", SprMTSPR>; // XS-Form instructions. Just 'sradi' // def SRADI : XSForm_1<31, 413, (ops GPRC:$rA, GPRC:$rS, u6imm:$SH), - "sradi $rA, $rS, $SH">, isPPC64; + "sradi $rA, $rS, $SH", IntRotateD>, isPPC64; // XO-Form instructions. Arithmetic instructions that can set overflow bit // def ADD4 : XOForm_1<31, 266, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "add $rT, $rA, $rB", + "add $rT, $rA, $rB", IntGeneral, [(set GPRC:$rT, (add GPRC:$rA, GPRC:$rB))]>; def ADD8 : XOForm_1<31, 266, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB), - "add $rT, $rA, $rB", + "add $rT, $rA, $rB", IntGeneral, [(set G8RC:$rT, (add G8RC:$rA, G8RC:$rB))]>; def ADDC : XOForm_1<31, 10, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "addc $rT, $rA, $rB", + "addc $rT, $rA, $rB", IntGeneral, []>; def ADDE : XOForm_1<31, 138, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "adde $rT, $rA, $rB", + "adde $rT, $rA, $rB", IntGeneral, []>; -def DIVD : XOForm_1<31, 489, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "divd $rT, $rA, $rB", - []>, isPPC64; -def DIVDU : XOForm_1<31, 457, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "divdu $rT, $rA, $rB", - []>, isPPC64; +def DIVD : XOForm_1<31, 489, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB), + "divd $rT, $rA, $rB", IntDivD, + [(set G8RC:$rT, (sdiv G8RC:$rA, G8RC:$rB))]>, isPPC64; +def DIVDU : XOForm_1<31, 457, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB), + "divdu $rT, $rA, $rB", IntDivD, + [(set G8RC:$rT, (udiv G8RC:$rA, G8RC:$rB))]>, isPPC64; def DIVW : XOForm_1<31, 491, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "divw $rT, $rA, $rB", + "divw $rT, $rA, $rB", IntDivW, [(set GPRC:$rT, (sdiv GPRC:$rA, GPRC:$rB))]>; def DIVWU : XOForm_1<31, 459, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "divwu $rT, $rA, $rB", + "divwu $rT, $rA, $rB", IntDivW, [(set GPRC:$rT, (udiv GPRC:$rA, GPRC:$rB))]>; +def MULHD : XOForm_1<31, 73, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB), + "mulhd $rT, $rA, $rB", IntMulHW, + [(set G8RC:$rT, (mulhs G8RC:$rA, G8RC:$rB))]>; +def MULHDU : XOForm_1<31, 9, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB), + "mulhdu $rT, $rA, $rB", IntMulHWU, + [(set G8RC:$rT, (mulhu G8RC:$rA, G8RC:$rB))]>; def MULHW : XOForm_1<31, 75, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "mulhw $rT, $rA, $rB", + "mulhw $rT, $rA, $rB", IntMulHW, [(set GPRC:$rT, (mulhs GPRC:$rA, GPRC:$rB))]>; def MULHWU : XOForm_1<31, 11, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "mulhwu $rT, $rA, $rB", + "mulhwu $rT, $rA, $rB", IntMulHWU, [(set GPRC:$rT, (mulhu GPRC:$rA, GPRC:$rB))]>; -def MULLD : XOForm_1<31, 233, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "mulld $rT, $rA, $rB", - []>, isPPC64; +def MULLD : XOForm_1<31, 233, 0, (ops G8RC:$rT, G8RC:$rA, G8RC:$rB), + "mulld $rT, $rA, $rB", IntMulHD, + [(set G8RC:$rT, (mul G8RC:$rA, G8RC:$rB))]>, isPPC64; def MULLW : XOForm_1<31, 235, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "mullw $rT, $rA, $rB", + "mullw $rT, $rA, $rB", IntMulHW, [(set GPRC:$rT, (mul GPRC:$rA, GPRC:$rB))]>; def SUBF : XOForm_1<31, 40, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "subf $rT, $rA, $rB", + "subf $rT, $rA, $rB", IntGeneral, [(set GPRC:$rT, (sub GPRC:$rB, GPRC:$rA))]>; def SUBFC : XOForm_1<31, 8, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "subfc $rT, $rA, $rB", + "subfc $rT, $rA, $rB", IntGeneral, []>; def SUBFE : XOForm_1<31, 136, 0, (ops GPRC:$rT, GPRC:$rA, GPRC:$rB), - "subfe $rT, $rA, $rB", + "subfe $rT, $rA, $rB", IntGeneral, []>; def ADDME : XOForm_3<31, 234, 0, (ops GPRC:$rT, GPRC:$rA), - "addme $rT, $rA", + "addme $rT, $rA", IntGeneral, []>; def ADDZE : XOForm_3<31, 202, 0, (ops GPRC:$rT, GPRC:$rA), - "addze $rT, $rA", + "addze $rT, $rA", IntGeneral, []>; def NEG : XOForm_3<31, 104, 0, (ops GPRC:$rT, GPRC:$rA), - "neg $rT, $rA", + "neg $rT, $rA", IntGeneral, [(set GPRC:$rT, (ineg GPRC:$rA))]>; def SUBFZE : XOForm_3<31, 200, 0, (ops GPRC:$rT, GPRC:$rA), - "subfze $rT, $rA", + "subfze $rT, $rA", IntGeneral, []>; // A-Form instructions. Most of the instructions executed in the FPU are of @@ -567,42 +620,42 @@ // def FMADD : AForm_1<63, 29, (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), - "fmadd $FRT, $FRA, $FRC, $FRB", + "fmadd $FRT, $FRA, $FRC, $FRB", FPFused, [(set F8RC:$FRT, (fadd (fmul F8RC:$FRA, F8RC:$FRC), F8RC:$FRB))]>; def FMADDS : AForm_1<59, 29, (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), - "fmadds $FRT, $FRA, $FRC, $FRB", + "fmadds $FRT, $FRA, $FRC, $FRB", FPGeneral, [(set F4RC:$FRT, (fadd (fmul F4RC:$FRA, F4RC:$FRC), F4RC:$FRB))]>; def FMSUB : AForm_1<63, 28, (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), - "fmsub $FRT, $FRA, $FRC, $FRB", + "fmsub $FRT, $FRA, $FRC, $FRB", FPFused, [(set F8RC:$FRT, (fsub (fmul F8RC:$FRA, F8RC:$FRC), F8RC:$FRB))]>; def FMSUBS : AForm_1<59, 28, (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), - "fmsubs $FRT, $FRA, $FRC, $FRB", + "fmsubs $FRT, $FRA, $FRC, $FRB", FPGeneral, [(set F4RC:$FRT, (fsub (fmul F4RC:$FRA, F4RC:$FRC), F4RC:$FRB))]>; def FNMADD : AForm_1<63, 31, (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), - "fnmadd $FRT, $FRA, $FRC, $FRB", + "fnmadd $FRT, $FRA, $FRC, $FRB", FPFused, [(set F8RC:$FRT, (fneg (fadd (fmul F8RC:$FRA, F8RC:$FRC), F8RC:$FRB)))]>; def FNMADDS : AForm_1<59, 31, (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), - "fnmadds $FRT, $FRA, $FRC, $FRB", + "fnmadds $FRT, $FRA, $FRC, $FRB", FPGeneral, [(set F4RC:$FRT, (fneg (fadd (fmul F4RC:$FRA, F4RC:$FRC), F4RC:$FRB)))]>; def FNMSUB : AForm_1<63, 30, (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), - "fnmsub $FRT, $FRA, $FRC, $FRB", + "fnmsub $FRT, $FRA, $FRC, $FRB", FPFused, [(set F8RC:$FRT, (fneg (fsub (fmul F8RC:$FRA, F8RC:$FRC), F8RC:$FRB)))]>; def FNMSUBS : AForm_1<59, 30, (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRC, F4RC:$FRB), - "fnmsubs $FRT, $FRA, $FRC, $FRB", + "fnmsubs $FRT, $FRA, $FRC, $FRB", FPGeneral, [(set F4RC:$FRT, (fneg (fsub (fmul F4RC:$FRA, F4RC:$FRC), F4RC:$FRB)))]>; // FSEL is artificially split into 4 and 8-byte forms for the result. To avoid @@ -611,43 +664,43 @@ // and 4/8 byte forms for the result and operand type.. def FSELD : AForm_1<63, 23, (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRC, F8RC:$FRB), - "fsel $FRT, $FRA, $FRC, $FRB", - []>; + "fsel $FRT, $FRA, $FRC, $FRB", FPGeneral, + [(set F8RC:$FRT, (PPCfsel F8RC:$FRA,F8RC:$FRC,F8RC:$FRB))]>; def FSELS : AForm_1<63, 23, (ops F4RC:$FRT, F8RC:$FRA, F4RC:$FRC, F4RC:$FRB), - "fsel $FRT, $FRA, $FRC, $FRB", - []>; + "fsel $FRT, $FRA, $FRC, $FRB", FPGeneral, + [(set F4RC:$FRT, (PPCfsel F8RC:$FRA,F4RC:$FRC,F4RC:$FRB))]>; def FADD : AForm_2<63, 21, (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB), - "fadd $FRT, $FRA, $FRB", + "fadd $FRT, $FRA, $FRB", FPGeneral, [(set F8RC:$FRT, (fadd F8RC:$FRA, F8RC:$FRB))]>; def FADDS : AForm_2<59, 21, (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB), - "fadds $FRT, $FRA, $FRB", + "fadds $FRT, $FRA, $FRB", FPGeneral, [(set F4RC:$FRT, (fadd F4RC:$FRA, F4RC:$FRB))]>; def FDIV : AForm_2<63, 18, (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB), - "fdiv $FRT, $FRA, $FRB", + "fdiv $FRT, $FRA, $FRB", FPDivD, [(set F8RC:$FRT, (fdiv F8RC:$FRA, F8RC:$FRB))]>; def FDIVS : AForm_2<59, 18, (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB), - "fdivs $FRT, $FRA, $FRB", + "fdivs $FRT, $FRA, $FRB", FPDivS, [(set F4RC:$FRT, (fdiv F4RC:$FRA, F4RC:$FRB))]>; def FMUL : AForm_3<63, 25, (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB), - "fmul $FRT, $FRA, $FRB", + "fmul $FRT, $FRA, $FRB", FPFused, [(set F8RC:$FRT, (fmul F8RC:$FRA, F8RC:$FRB))]>; def FMULS : AForm_3<59, 25, (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB), - "fmuls $FRT, $FRA, $FRB", + "fmuls $FRT, $FRA, $FRB", FPGeneral, [(set F4RC:$FRT, (fmul F4RC:$FRA, F4RC:$FRB))]>; def FSUB : AForm_2<63, 20, (ops F8RC:$FRT, F8RC:$FRA, F8RC:$FRB), - "fsub $FRT, $FRA, $FRB", + "fsub $FRT, $FRA, $FRB", FPGeneral, [(set F8RC:$FRT, (fsub F8RC:$FRA, F8RC:$FRB))]>; def FSUBS : AForm_2<59, 20, (ops F4RC:$FRT, F4RC:$FRA, F4RC:$FRB), - "fsubs $FRT, $FRA, $FRB", + "fsubs $FRT, $FRA, $FRB", FPGeneral, [(set F4RC:$FRT, (fsub F4RC:$FRA, F4RC:$FRB))]>; // M-Form instructions. rotate and mask instructions. @@ -656,29 +709,36 @@ // RLWIMI can be commuted if the rotate amount is zero. def RLWIMI : MForm_2<20, (ops GPRC:$rA, GPRC:$rSi, GPRC:$rS, u5imm:$SH, u5imm:$MB, - u5imm:$ME), "rlwimi $rA, $rS, $SH, $MB, $ME">; + u5imm:$ME), "rlwimi $rA, $rS, $SH, $MB, $ME", IntRotate, + []>; def RLDIMI : MDForm_1<30, 3, (ops G8RC:$rA, G8RC:$rSi, G8RC:$rS, u6imm:$SH, u6imm:$MB), - "rldimi $rA, $rS, $SH, $MB">, isPPC64; + "rldimi $rA, $rS, $SH, $MB", IntRotateD, + []>, isPPC64; } def RLWINM : MForm_2<21, (ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME), - "rlwinm $rA, $rS, $SH, $MB, $ME">; + "rlwinm $rA, $rS, $SH, $MB, $ME", IntGeneral, + []>; def RLWINMo : MForm_2<21, (ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME), - "rlwinm. $rA, $rS, $SH, $MB, $ME">, isDOT; + "rlwinm. $rA, $rS, $SH, $MB, $ME", IntGeneral, + []>, isDOT; def RLWNM : MForm_2<23, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB, u5imm:$MB, u5imm:$ME), - "rlwnm $rA, $rS, $rB, $MB, $ME">; + "rlwnm $rA, $rS, $rB, $MB, $ME", IntGeneral, + []>; // MD-Form instructions. 64 bit rotate instructions. // def RLDICL : MDForm_1<30, 0, (ops G8RC:$rA, G8RC:$rS, u6imm:$SH, u6imm:$MB), - "rldicl $rA, $rS, $SH, $MB">, isPPC64; + "rldicl $rA, $rS, $SH, $MB", IntRotateD, + []>, isPPC64; def RLDICR : MDForm_1<30, 1, (ops G8RC:$rA, G8RC:$rS, u6imm:$SH, u6imm:$ME), - "rldicr $rA, $rS, $SH, $ME">, isPPC64; + "rldicr $rA, $rS, $SH, $ME", IntRotateD, + []>, isPPC64; //===----------------------------------------------------------------------===// // PowerPC Instruction Patterns @@ -701,8 +761,27 @@ // XOR an arbitrary immediate. def : Pat<(xor GPRC:$in, imm:$imm), (XORIS (XORI GPRC:$in, (LO16 imm:$imm)), (HI16 imm:$imm))>; - - +def : Pat<(or (shl GPRC:$rS, GPRC:$rB), + (srl GPRC:$rS, (sub 32, GPRC:$rB))), + (RLWNM GPRC:$rS, GPRC:$rB, 0, 31)>; + +def : Pat<(zext GPRC:$in), + (RLDICL (OR4To8 GPRC:$in, GPRC:$in), 0, 32)>; +def : Pat<(anyext GPRC:$in), + (OR4To8 GPRC:$in, GPRC:$in)>; +def : Pat<(trunc G8RC:$in), + (OR8To4 G8RC:$in, G8RC:$in)>; + +// SHL +def : Pat<(shl GPRC:$in, imm:$imm), + (RLWINM GPRC:$in, imm:$imm, 0, (SHL32 imm:$imm))>; +def : Pat<(shl G8RC:$in, imm:$imm), + (RLDICR G8RC:$in, imm:$imm, (SHL64 imm:$imm))>; +// SRL +def : Pat<(srl GPRC:$in, imm:$imm), + (RLWINM GPRC:$in, (SRL32 imm:$imm), imm:$imm, 31)>; +def : Pat<(srl G8RC:$in, imm:$imm), + (RLDICL G8RC:$in, (SRL64 imm:$imm), imm:$imm)>; // Same as above, but using a temporary. FIXME: implement temporaries :) /* @@ -711,7 +790,6 @@ (XORIS GPRC:$tmp, (HI16 imm:$imm))]>; */ - //===----------------------------------------------------------------------===// // PowerPCInstrInfo Definition // Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.36 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.36.2.1 --- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.36 Tue Oct 18 11:51:22 2005 +++ llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp Wed Nov 16 12:32:38 2005 @@ -26,6 +26,7 @@ #include "llvm/Target/TargetOptions.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/MathExtras.h" #include "llvm/ADT/STLExtras.h" #include #include @@ -294,6 +295,11 @@ // Get the number of bytes to allocate from the FrameInfo unsigned NumBytes = MFI->getStackSize(); + + // Get the alignments provided by the target, and the maximum alignment + // (if any) of the fixed frame objects. + unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); + unsigned MaxAlign = MFI->getMaxAlignment(); // If we have calls, we cannot use the red zone to store callee save registers // and we must set up a stack frame, so calculate the necessary size here. @@ -307,14 +313,15 @@ // If we are a leaf function, and use up to 224 bytes of stack space, // and don't have a frame pointer, then we do not need to adjust the stack // pointer (we fit in the Red Zone). - if ((NumBytes == 0) || (NumBytes <= 224 && !hasFP(MF) && !MFI->hasCalls())) { + if ((NumBytes == 0) || (NumBytes <= 224 && !hasFP(MF) && !MFI->hasCalls() && + MaxAlign <= TargetAlign)) { MFI->setStackSize(0); return; } // Add the size of R1 to NumBytes size for the store of R1 to the bottom // of the stack and round the size to a multiple of the alignment. - unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); + unsigned Align = std::max(TargetAlign, MaxAlign); unsigned GPRSize = 4; unsigned Size = hasFP(MF) ? GPRSize + GPRSize : GPRSize; NumBytes = (NumBytes+Size+Align-1)/Align*Align; @@ -336,7 +343,23 @@ MI = BuildMI(PPC::STWUX, 3).addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0); MBB.insert(MBBI, MI); } - + + // If there is a preferred stack alignment, align R1 now + // FIXME: If this ever matters, this could be made more efficient by folding + // this into the code above, so that we don't issue two store+update + // instructions. + if (MaxAlign > TargetAlign) { + assert(isPowerOf2_32(MaxAlign) && MaxAlign < 32767 && "Invalid alignment!"); + MI = BuildMI(PPC::RLWINM, 4, PPC::R0).addReg(PPC::R1).addImm(0) + .addImm(32-Log2_32(MaxAlign)).addImm(31); + MBB.insert(MBBI, MI); + MI = BuildMI(PPC::SUBFIC, 2, PPC::R0).addReg(PPC::R0).addImm(MaxAlign); + MBB.insert(MBBI, MI); + MI = BuildMI(PPC::STWUX, 3).addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0); + MBB.insert(MBBI, MI); + } + + // If there is a frame pointer, copy R1 (SP) into R31 (FP) if (hasFP(MF)) { MI = BuildMI(PPC::STW, 3).addReg(PPC::R31).addSImm(GPRSize).addReg(PPC::R1); MBB.insert(MBBI, MI); Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.td diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.td:1.18 llvm/lib/Target/PowerPC/PPCRegisterInfo.td:1.18.2.1 --- llvm/lib/Target/PowerPC/PPCRegisterInfo.td:1.18 Mon Oct 17 19:28:58 2005 +++ llvm/lib/Target/PowerPC/PPCRegisterInfo.td Wed Nov 16 12:32:38 2005 @@ -21,6 +21,12 @@ field bits<5> Num = num; } +// GP8 - One of the 32 64-bit general-purpose registers +class GP8 : PPCReg { + field bits<5> Num = Alias.Num; + let Aliases = [Alias]; +} + // SPR - One of the 32-bit special-purpose registers class SPR num, string n> : PPCReg { field bits<5> Num = num; @@ -54,6 +60,24 @@ def R28 : GPR<28, "r28">; def R29 : GPR<29, "r29">; def R30 : GPR<30, "r30">; def R31 : GPR<31, "r31">; +// 64-bit General-purpose registers +def X0 : GP8< R0>; def X1 : GP8< R1>; +def X2 : GP8< R2>; def X3 : GP8< R3>; +def X4 : GP8< R4>; def X5 : GP8< R5>; +def X6 : GP8< R6>; def X7 : GP8< R7>; +def X8 : GP8< R8>; def X9 : GP8< R9>; +def X10 : GP8; def X11 : GP8; +def X12 : GP8; def X13 : GP8; +def X14 : GP8; def X15 : GP8; +def X16 : GP8; def X17 : GP8; +def X18 : GP8; def X19 : GP8; +def X20 : GP8; def X21 : GP8; +def X22 : GP8; def X23 : GP8; +def X24 : GP8; def X25 : GP8; +def X26 : GP8; def X27 : GP8; +def X28 : GP8; def X29 : GP8; +def X30 : GP8; def X31 : GP8; + // Floating-point registers def F0 : FPR< 0, "f0">; def F1 : FPR< 1, "f1">; def F2 : FPR< 2, "f2">; def F3 : FPR< 3, "f3">; @@ -111,9 +135,9 @@ }]; } def G8RC : RegisterClass<"PPC", i64, 64, - [R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, - R30, R29, R28, R27, R26, R25, R24, R23, R22, R21, R20, R19, R18, R17, - R16, R15, R14, R13, R31, R0, R1, LR]> + [X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, + X30, X29, X28, X27, X26, X25, X24, X23, X22, X21, X20, X19, X18, X17, + X16, X15, X14, X13, X31, X0, X1]> { let MethodProtos = [{ iterator allocation_order_begin(MachineFunction &MF) const; @@ -127,9 +151,9 @@ G8RCClass::iterator G8RCClass::allocation_order_end(MachineFunction &MF) const { if (hasFP(MF)) - return end()-4; - else return end()-3; + else + return end()-2; } }]; } Index: llvm/lib/Target/PowerPC/PPCSchedule.td diff -u llvm/lib/Target/PowerPC/PPCSchedule.td:1.1 llvm/lib/Target/PowerPC/PPCSchedule.td:1.1.2.1 --- llvm/lib/Target/PowerPC/PPCSchedule.td:1.1 Tue Oct 18 11:23:40 2005 +++ llvm/lib/Target/PowerPC/PPCSchedule.td Wed Nov 16 12:32:38 2005 @@ -7,20 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "../TargetSchedule.td" - -//===----------------------------------------------------------------------===// -// PowerPC chips sets supported by scheduling (Apple naming) -// -def G3 : Processor; -def G4 : Processor; -def G4Plus : Processor; -def G5 : Processor; - //===----------------------------------------------------------------------===// // Functional units across PowerPC chips sets // -def NoUnit : FuncUnit; // Instruction not supported on chip set def BPU : FuncUnit; // Branch unit def SLU : FuncUnit; // Store/load unit def SRU : FuncUnit; // special register unit @@ -64,17 +53,17 @@ def LdStDCBA : InstrItinClass; def LdStDCBF : InstrItinClass; def LdStDCBI : InstrItinClass; -def LdStDCBT : InstrItinClass; +def LdStGeneral : InstrItinClass; def LdStDSS : InstrItinClass; def LdStICBI : InstrItinClass; -def LdStLBZUX : InstrItinClass; +def LdStUX : InstrItinClass; def LdStLD : InstrItinClass; def LdStLDARX : InstrItinClass; def LdStLFD : InstrItinClass; def LdStLFDU : InstrItinClass; def LdStLHA : InstrItinClass; def LdStLMW : InstrItinClass; -def LdStLVEBX : InstrItinClass; +def LdStLVecX : InstrItinClass; def LdStLWA : InstrItinClass; def LdStLWARX : InstrItinClass; def LdStSLBIA : InstrItinClass; @@ -116,10 +105,10 @@ //===----------------------------------------------------------------------===// // Processor instruction itineraries. -#include "PPCScheduleG3.td" -#include "PPCScheduleG4.td" -#include "PPCScheduleG4Plus.td" -#include "PPCScheduleG5.td" +include "PPCScheduleG3.td" +include "PPCScheduleG4.td" +include "PPCScheduleG4Plus.td" +include "PPCScheduleG5.td" //===----------------------------------------------------------------------===// // Instruction to itinerary class map - When add new opcodes to the supported @@ -163,8 +152,8 @@ // dcbf LdStDCBF // dcbi LdStDCBI // dcbst LdStDCBF -// dcbt LdStDCBT -// dcbtst LdStDCBT +// dcbt LdStGeneral +// dcbtst LdStGeneral // dcbz LdStDCBF // divd IntDivD // divdu IntDivD @@ -173,9 +162,9 @@ // dss LdStDSS // dst LdStDSS // dstst LdStDSS -// eciwx LdStDCBT -// ecowx LdStDCBT -// eieio LdStDCBT +// eciwx LdStGeneral +// ecowx LdStGeneral +// eieio LdStGeneral // eqv IntGeneral // extsb IntGeneral // extsh IntGeneral @@ -215,10 +204,10 @@ // fsubs FPGeneral // icbi LdStICBI // isync SprISYNC -// lbz LdStDCBT -// lbzu LdStDCBT -// lbzux LdStLBZUX -// lbzx LdStDCBT +// lbz LdStGeneral +// lbzu LdStGeneral +// lbzux LdStUX +// lbzx LdStGeneral // ld LdStLD // ldarx LdStLDARX // ldu LdStLD @@ -236,30 +225,30 @@ // lhau LdStLHA // lhaux LdStLHA // lhax LdStLHA -// lhbrx LdStDCBT -// lhz LdStDCBT -// lhzu LdStDCBT -// lhzux LdStLBZUX -// lhzx LdStDCBT +// lhbrx LdStGeneral +// lhz LdStGeneral +// lhzu LdStGeneral +// lhzux LdStUX +// lhzx LdStGeneral // lmw LdStLMW // lswi LdStLMW // lswx LdStLMW -// lvebx LdStLVEBX -// lvehx LdStLVEBX -// lvewx LdStLVEBX -// lvsl LdStLVEBX -// lvsr LdStLVEBX -// lvx LdStLVEBX -// lvxl LdStLVEBX +// lvebx LdStLVecX +// lvehx LdStLVecX +// lvewx LdStLVecX +// lvsl LdStLVecX +// lvsr LdStLVecX +// lvx LdStLVecX +// lvxl LdStLVecX // lwa LdStLWA // lwarx LdStLWARX // lwaux LdStLHA // lwax LdStLHA -// lwbrx LdStDCBT -// lwz LdStDCBT -// lwzu LdStDCBT -// lwzux LdStLBZUX -// lwzx LdStDCBT +// lwbrx LdStGeneral +// lwz LdStGeneral +// lwzu LdStGeneral +// lwzux LdStUX +// lwzx LdStGeneral // mcrf BrMCR // mcrfs FPGeneral // mcrxr BrMCRX @@ -320,29 +309,29 @@ // srawi IntShift // srd IntRotateD // srw IntGeneral -// stb LdStDCBT -// stbu LdStDCBT -// stbux LdStDCBT -// stbx LdStDCBT +// stb LdStGeneral +// stbu LdStGeneral +// stbux LdStGeneral +// stbx LdStGeneral // std LdStSTD // stdcx. LdStSTDCX // stdu LdStSTD // stdux LdStSTD // stdx LdStSTD -// stfd LdStLBZUX -// stfdu LdStLBZUX -// stfdux LdStLBZUX -// stfdx LdStLBZUX -// stfiwx LdStLBZUX -// stfs LdStLBZUX -// stfsu LdStLBZUX -// stfsux LdStLBZUX -// stfsx LdStLBZUX -// sth LdStDCBT -// sthbrx LdStDCBT -// sthu LdStDCBT -// sthux LdStDCBT -// sthx LdStDCBT +// stfd LdStUX +// stfdu LdStUX +// stfdux LdStUX +// stfdx LdStUX +// stfiwx LdStUX +// stfs LdStUX +// stfsu LdStUX +// stfsux LdStUX +// stfsx LdStUX +// sth LdStGeneral +// sthbrx LdStGeneral +// sthu LdStGeneral +// sthux LdStGeneral +// sthx LdStGeneral // stmw LdStLMW // stswi LdStLMW // stswx LdStLMW @@ -351,12 +340,12 @@ // stvewx LdStSTVEBX // stvx LdStSTVEBX // stvxl LdStSTVEBX -// stw LdStDCBT -// stwbrx LdStDCBT +// stw LdStGeneral +// stwbrx LdStGeneral // stwcx. LdStSTWCX -// stwu LdStDCBT -// stwux LdStDCBT -// stwx LdStDCBT +// stwu LdStGeneral +// stwux LdStGeneral +// stwx LdStGeneral // subf IntGeneral // subfc IntGeneral // subfe IntGeneral @@ -517,4 +506,3 @@ // xori IntGeneral // xoris IntGeneral // - Index: llvm/lib/Target/PowerPC/PPCScheduleG3.td diff -u llvm/lib/Target/PowerPC/PPCScheduleG3.td:1.2 llvm/lib/Target/PowerPC/PPCScheduleG3.td:1.2.2.1 --- llvm/lib/Target/PowerPC/PPCScheduleG3.td:1.2 Tue Oct 18 11:59:23 2005 +++ llvm/lib/Target/PowerPC/PPCScheduleG3.td Wed Nov 16 12:32:38 2005 @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// -def G3Itineraries : ProcessorItineraries]>, InstrItinData]>, InstrItinData]>, @@ -31,9 +31,9 @@ InstrItinData]>, InstrItinData]>, InstrItinData]>, - InstrItinData]>, + InstrItinData]>, InstrItinData]>, - InstrItinData]>, + InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, @@ -59,5 +59,5 @@ InstrItinData]>, InstrItinData]>, InstrItinData]>, - InstrItinData]>, + InstrItinData]> ]>; Index: llvm/lib/Target/PowerPC/PPCScheduleG4.td diff -u llvm/lib/Target/PowerPC/PPCScheduleG4.td:1.2 llvm/lib/Target/PowerPC/PPCScheduleG4.td:1.2.2.1 --- llvm/lib/Target/PowerPC/PPCScheduleG4.td:1.2 Tue Oct 18 11:59:23 2005 +++ llvm/lib/Target/PowerPC/PPCScheduleG4.td Wed Nov 16 12:32:38 2005 @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -def G4Itineraries : ProcessorItineraries]>, InstrItinData]>, InstrItinData]>, @@ -30,15 +30,15 @@ InstrItinData]>, InstrItinData]>, InstrItinData]>, - InstrItinData]>, + InstrItinData]>, InstrItinData]>, InstrItinData]>, - InstrItinData]>, + InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, - InstrItinData]>, + InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, Index: llvm/lib/Target/PowerPC/PPCScheduleG4Plus.td diff -u llvm/lib/Target/PowerPC/PPCScheduleG4Plus.td:1.2 llvm/lib/Target/PowerPC/PPCScheduleG4Plus.td:1.2.2.1 --- llvm/lib/Target/PowerPC/PPCScheduleG4Plus.td:1.2 Tue Oct 18 11:59:23 2005 +++ llvm/lib/Target/PowerPC/PPCScheduleG4Plus.td Wed Nov 16 12:32:38 2005 @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -def G4PlusItineraries : ProcessorItineraries]>, InstrItinData]>, InstrItinData]>, @@ -30,15 +30,15 @@ InstrItinData]>, InstrItinData]>, InstrItinData]>, - InstrItinData]>, + InstrItinData]>, InstrItinData]>, InstrItinData]>, - InstrItinData]>, + InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, - InstrItinData]>, + InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, Index: llvm/lib/Target/PowerPC/PPCScheduleG5.td diff -u llvm/lib/Target/PowerPC/PPCScheduleG5.td:1.2 llvm/lib/Target/PowerPC/PPCScheduleG5.td:1.2.2.1 --- llvm/lib/Target/PowerPC/PPCScheduleG5.td:1.2 Tue Oct 18 11:59:23 2005 +++ llvm/lib/Target/PowerPC/PPCScheduleG5.td Wed Nov 16 12:32:38 2005 @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -def G5Itineraries : ProcessorItineraries]>, InstrItinData]>, InstrItinData]>, @@ -34,17 +34,17 @@ InstrItinData]>, InstrItinData]>, InstrItinData]>, - InstrItinData]>, + InstrItinData]>, InstrItinData]>, InstrItinData]>, - InstrItinData]>, + InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, - InstrItinData]>, + InstrItinData]>, InstrItinData]>, InstrItinData]>, InstrItinData]>, // needs work Index: llvm/lib/Target/PowerPC/PPCSubtarget.cpp diff -u llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.10 llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.10.2.1 --- llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.10 Mon Oct 17 19:56:42 2005 +++ llvm/lib/Target/PowerPC/PPCSubtarget.cpp Wed Nov 16 12:32:38 2005 @@ -15,7 +15,7 @@ #include "PPC.h" #include "llvm/Module.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Target/SubtargetFeature.h" +#include "PPCGenSubtarget.inc" using namespace llvm; PPCTargetEnum llvm::PPCTarget = TargetDefault; @@ -29,61 +29,8 @@ " Enable Darwin codegen"), clEnumValEnd), cl::location(PPCTarget), cl::init(TargetDefault)); -} - -enum PowerPCFeature { - PowerPCFeature64Bit = 1 << 0, - PowerPCFeatureAltivec = 1 << 1, - PowerPCFeatureFSqrt = 1 << 2, - PowerPCFeatureGPUL = 1 << 3, - PowerPCFeature64BRegs = 1 << 4 -}; - -/// Sorted (by key) array of values for CPU subtype. -static const SubtargetFeatureKV PowerPCSubTypeKV[] = { - { "601" , "Select the PowerPC 601 processor", 0 }, - { "602" , "Select the PowerPC 602 processor", 0 }, - { "603" , "Select the PowerPC 603 processor", 0 }, - { "603e" , "Select the PowerPC 603e processor", 0 }, - { "603ev" , "Select the PowerPC 603ev processor", 0 }, - { "604" , "Select the PowerPC 604 processor", 0 }, - { "604e" , "Select the PowerPC 604e processor", 0 }, - { "620" , "Select the PowerPC 620 processor", 0 }, - { "7400" , "Select the PowerPC 7400 (G4) processor", - PowerPCFeatureAltivec }, - { "7450" , "Select the PowerPC 7450 (G4+) processor", - PowerPCFeatureAltivec }, - { "750" , "Select the PowerPC 750 (G3) processor", 0 }, - { "970" , "Select the PowerPC 970 (G5 - GPUL) processor", - PowerPCFeature64Bit | PowerPCFeatureAltivec | - PowerPCFeatureFSqrt | PowerPCFeatureGPUL }, - { "g3" , "Select the PowerPC G3 (750) processor", 0 }, - { "g4" , "Select the PowerPC G4 (7400) processor", - PowerPCFeatureAltivec }, - { "g4+" , "Select the PowerPC G4+ (7450) processor", - PowerPCFeatureAltivec }, - { "g5" , "Select the PowerPC g5 (970 - GPUL) processor", - PowerPCFeature64Bit | PowerPCFeatureAltivec | - PowerPCFeatureFSqrt | PowerPCFeatureGPUL }, - { "generic", "Select instructions for a generic PowerPC processor", 0 } -}; -/// Length of PowerPCSubTypeKV. -static const unsigned PowerPCSubTypeKVSize = sizeof(PowerPCSubTypeKV) - / sizeof(SubtargetFeatureKV); - -/// Sorted (by key) array of values for CPU features. -static SubtargetFeatureKV PowerPCFeatureKV[] = { - { "64bit" , "Should 64 bit instructions be used" , PowerPCFeature64Bit }, - { "64bitregs", "Should 64 bit registers be used" , PowerPCFeature64BRegs }, - { "altivec", "Should Altivec instructions be used" , PowerPCFeatureAltivec }, - { "fsqrt" , "Should the fsqrt instruction be used", PowerPCFeatureFSqrt }, - { "gpul" , "Should GPUL instructions be used" , PowerPCFeatureGPUL } - }; -/// Length of PowerPCFeatureKV. -static const unsigned PowerPCFeatureKVSize = sizeof(PowerPCFeatureKV) - / sizeof(SubtargetFeatureKV); - - +} + #if defined(__APPLE__) #include #include @@ -121,22 +68,26 @@ } #endif + PPCSubtarget::PPCSubtarget(const Module &M, const std::string &FS) - : StackAlignment(16), IsGigaProcessor(false), IsAIX(false), IsDarwin(false) { + : StackAlignment(16) + , InstrItins() + , IsGigaProcessor(false) + , Is64Bit(false) + , Has64BitRegs(false) + , HasAltivec(false) + , HasFSQRT(false) + , IsAIX(false) + , IsDarwin(false) { // Determine default and user specified characteristics std::string CPU = "generic"; #if defined(__APPLE__) CPU = GetCurrentPowerPCCPU(); #endif - uint32_t Bits = - SubtargetFeatures::Parse(FS, CPU, - PowerPCSubTypeKV, PowerPCSubTypeKVSize, - PowerPCFeatureKV, PowerPCFeatureKVSize); - IsGigaProcessor = (Bits & PowerPCFeatureGPUL ) != 0; - Is64Bit = (Bits & PowerPCFeature64Bit) != 0; - HasFSQRT = (Bits & PowerPCFeatureFSqrt) != 0; - Has64BitRegs = (Bits & PowerPCFeature64BRegs) != 0; + + // Parse features string. + ParseSubtargetFeatures(FS, CPU); // Set the boolean corresponding to the current target triple, or the default // if one cannot be determined, to true. Index: llvm/lib/Target/PowerPC/PPCSubtarget.h diff -u llvm/lib/Target/PowerPC/PPCSubtarget.h:1.8 llvm/lib/Target/PowerPC/PPCSubtarget.h:1.8.2.1 --- llvm/lib/Target/PowerPC/PPCSubtarget.h:1.8 Mon Oct 17 19:56:42 2005 +++ llvm/lib/Target/PowerPC/PPCSubtarget.h Wed Nov 16 12:32:38 2005 @@ -14,6 +14,7 @@ #ifndef POWERPCSUBTARGET_H #define POWERPCSUBTARGET_H +#include "llvm/Target/TargetInstrItineraries.h" #include "llvm/Target/TargetSubtarget.h" #include @@ -26,11 +27,15 @@ /// stackAlignment - The minimum alignment known to hold of the stack frame on /// entry to the function and which must be maintained by every function. unsigned StackAlignment; + + /// Selected instruction itineraries (one entry per itinerary class.) + InstrItineraryData InstrItins; /// Used by the ISel to turn in optimizations for POWER4-derived architectures bool IsGigaProcessor; bool Is64Bit; bool Has64BitRegs; + bool HasAltivec; bool HasFSQRT; bool IsAIX; bool IsDarwin; @@ -39,18 +44,28 @@ /// of the specified module. /// PPCSubtarget(const Module &M, const std::string &FS); + + /// ParseSubtargetFeatures - Parses features string setting specified + /// subtarget options. Definition of function is auto generated by tblgen. + void ParseSubtargetFeatures(const std::string &FS, const std::string &CPU); /// getStackAlignment - Returns the minimum alignment known to hold of the /// stack frame on entry to the function and which must be maintained by every /// function for this subtarget. unsigned getStackAlignment() const { return StackAlignment; } + + /// getInstrItins - Return the instruction itineraies based on subtarget + /// selection. + const InstrItineraryData getInstrItineraryData() const { return InstrItins; } + bool hasFSQRT() const { return HasFSQRT; } + bool has64BitRegs() const { return Has64BitRegs; } + bool hasAltivec() const { return HasAltivec; } bool isAIX() const { return IsAIX; } bool isDarwin() const { return IsDarwin; } bool is64Bit() const { return Is64Bit; } - bool has64BitRegs() const { return Has64BitRegs; } bool isGigaProcessor() const { return IsGigaProcessor; } }; } // End llvm namespace Index: llvm/lib/Target/PowerPC/PPCTargetMachine.cpp diff -u llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.75 llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.75.2.1 --- llvm/lib/Target/PowerPC/PPCTargetMachine.cpp:1.75 Mon Oct 17 19:28:58 2005 +++ llvm/lib/Target/PowerPC/PPCTargetMachine.cpp Wed Nov 16 12:32:38 2005 @@ -64,7 +64,8 @@ PPCTargetMachine::PPCTargetMachine(const Module &M, IntrinsicLowering *IL, const std::string &FS) : TargetMachine("PowerPC", IL, false, 4, 4, 4, 4, 4, 4, 2, 1, 1), - Subtarget(M, FS), FrameInfo(*this, false), JITInfo(*this) { + Subtarget(M, FS), FrameInfo(*this, false), JITInfo(*this), + InstrItins(Subtarget.getInstrItineraryData()) { if (TargetDefault == PPCTarget) { if (Subtarget.isAIX()) PPCTarget = TargetAIX; if (Subtarget.isDarwin()) PPCTarget = TargetDarwin; @@ -76,11 +77,12 @@ /// bool PPCTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType) { + CodeGenFileType FileType, + bool Fast) { if (FileType != TargetMachine::AssemblyFile) return true; // Run loop strength reduction before anything else. - PM.add(createLoopStrengthReducePass()); + if (!Fast) PM.add(createLoopStrengthReducePass()); // FIXME: Implement efficient support for garbage collection intrinsics. PM.add(createLowerGCPass()); @@ -89,7 +91,7 @@ PM.add(createLowerInvokePass()); // Clean up after other passes, e.g. merging critical edges. - PM.add(createCFGSimplificationPass()); + if (!Fast) PM.add(createCFGSimplificationPass()); // FIXME: Implement the switch instruction in the instruction selector! PM.add(createLowerSwitchPass()); Index: llvm/lib/Target/PowerPC/PPCTargetMachine.h diff -u llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.14 llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.14.2.1 --- llvm/lib/Target/PowerPC/PPCTargetMachine.h:1.14 Sun Oct 16 00:39:50 2005 +++ llvm/lib/Target/PowerPC/PPCTargetMachine.h Wed Nov 16 12:32:38 2005 @@ -27,10 +27,11 @@ class IntrinsicLowering; class PPCTargetMachine : public TargetMachine { - PPCInstrInfo InstrInfo; - PPCSubtarget Subtarget; - PPCFrameInfo FrameInfo; - PPCJITInfo JITInfo; + PPCInstrInfo InstrInfo; + PPCSubtarget Subtarget; + PPCFrameInfo FrameInfo; + PPCJITInfo JITInfo; + InstrItineraryData InstrItins; public: PPCTargetMachine(const Module &M, IntrinsicLowering *IL, const std::string &FS); @@ -42,13 +43,17 @@ virtual const MRegisterInfo *getRegisterInfo() const { return &InstrInfo.getRegisterInfo(); } + virtual const InstrItineraryData getInstrItineraryData() const { + return InstrItins; + } + static unsigned getJITMatchQuality(); static unsigned getModuleMatchQuality(const Module &M); virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType); + CodeGenFileType FileType, bool Fast); bool addPassesToEmitMachineCode(FunctionPassManager &PM, MachineCodeEmitter &MCE); Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.33 llvm/lib/Target/PowerPC/README.txt:1.33.2.1 --- llvm/lib/Target/PowerPC/README.txt:1.33 Tue Oct 18 01:30:51 2005 +++ llvm/lib/Target/PowerPC/README.txt Wed Nov 16 12:32:38 2005 @@ -121,3 +121,122 @@ If we exposed the srl & mask ops after the MFCR that we are doing to select the correct CR bit, then we could fold the slwi into the rlwinm before it. + +===-------------------------------------------------------------------------=== + +#define ARRAY_LENGTH 16 + +union bitfield { + struct { +#ifndef __ppc__ + unsigned int field0 : 6; + unsigned int field1 : 6; + unsigned int field2 : 6; + unsigned int field3 : 6; + unsigned int field4 : 3; + unsigned int field5 : 4; + unsigned int field6 : 1; +#else + unsigned int field6 : 1; + unsigned int field5 : 4; + unsigned int field4 : 3; + unsigned int field3 : 6; + unsigned int field2 : 6; + unsigned int field1 : 6; + unsigned int field0 : 6; +#endif + } bitfields, bits; + unsigned int u32All; + signed int i32All; + float f32All; +}; + + +typedef struct program_t { + union bitfield array[ARRAY_LENGTH]; + int size; + int loaded; +} program; + + +void AdjustBitfields(program* prog, unsigned int fmt1) +{ + unsigned int shift = 0; + unsigned int texCount = 0; + unsigned int i; + + for (i = 0; i < 8; i++) + { + prog->array[i].bitfields.field0 = texCount; + prog->array[i].bitfields.field1 = texCount + 1; + prog->array[i].bitfields.field2 = texCount + 2; + prog->array[i].bitfields.field3 = texCount + 3; + + texCount += (fmt1 >> shift) & 0x7; + shift += 3; + } +} + +In the loop above, the bitfield adds get generated as +(add (shl bitfield, C1), (shl C2, C1)) where C2 is 1, 2 or 3. + +Since the input to the (or and, and) is an (add) rather than a (shl), the shift +doesn't get folded into the rlwimi instruction. We should ideally see through +things like this, rather than forcing llvm to generate the equivalent + +(shl (add bitfield, C2), C1) with some kind of mask. + +===-------------------------------------------------------------------------=== + +Compile this (standard bitfield insert of a constant): +void %test(uint* %tmp1) { + %tmp2 = load uint* %tmp1 ; [#uses=1] + %tmp5 = or uint %tmp2, 257949696 ; [#uses=1] + %tmp6 = and uint %tmp5, 4018143231 ; [#uses=1] + store uint %tmp6, uint* %tmp1 + ret void +} + +to: + +_test: + lwz r0,0(r3) + li r2,123 + rlwimi r0,r2,21,3,10 + stw r0,0(r3) + blr + +instead of: + +_test: + lis r2, -4225 + lwz r4, 0(r3) + ori r2, r2, 65535 + oris r4, r4, 3936 + and r2, r4, r2 + stw r2, 0(r3) + blr + +===-------------------------------------------------------------------------=== + +Compile this: + +int %f1(int %a, int %b) { + %tmp.1 = and int %a, 15 ; [#uses=1] + %tmp.3 = and int %b, 240 ; [#uses=1] + %tmp.4 = or int %tmp.3, %tmp.1 ; [#uses=1] + ret int %tmp.4 +} + +without a copy. We make this currently: + +_f1: + rlwinm r2, r4, 0, 24, 27 + rlwimi r2, r3, 0, 28, 31 + or r3, r2, r2 + blr + +The two-addr pass or RA needs to learn when it is profitable to commute an +instruction to avoid a copy AFTER the 2-addr instruction. The 2-addr pass +currently only commutes to avoid inserting a copy BEFORE the two addr instr. + From bocchino at cs.uiuc.edu Wed Nov 16 12:32:57 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:32:57 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Target/X86/README.txt X86.h X86ISelLowering.cpp X86ISelLowering.h X86ISelPattern.cpp X86TargetMachine.cpp X86TargetMachine.h Message-ID: <200511161832.MAA21212@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt added (r1.16.4.2) X86.h updated: 1.36 -> 1.36.2.1 X86ISelLowering.cpp added (r1.1.2.2) X86ISelLowering.h added (r1.1.2.2) X86ISelPattern.cpp updated: 1.183 -> 1.183.2.1 X86TargetMachine.cpp updated: 1.86 -> 1.86.2.1 X86TargetMachine.h updated: 1.30 -> 1.30.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+1139 -1069) README.txt | 75 +++ X86.h | 12 X86ISelLowering.cpp | 916 ++++++++++++++++++++++++++++++++++++++++++++ X86ISelLowering.h | 131 ++++++ X86ISelPattern.cpp | 1059 --------------------------------------------------- X86TargetMachine.cpp | 7 X86TargetMachine.h | 8 7 files changed, 1139 insertions(+), 1069 deletions(-) Index: llvm/lib/Target/X86/README.txt diff -c /dev/null llvm/lib/Target/X86/README.txt:1.16.4.2 *** /dev/null Wed Nov 16 12:32:55 2005 --- llvm/lib/Target/X86/README.txt Wed Nov 16 12:32:45 2005 *************** *** 0 **** --- 1,75 ---- + //===---------------------------------------------------------------------===// + // Random ideas for the X86 backend. + //===---------------------------------------------------------------------===// + + Add a MUL2U and MUL2S nodes to represent a multiply that returns both the + Hi and Lo parts (combination of MUL and MULH[SU] into one node). Add this to + X86, & make the dag combiner produce it when needed. This will eliminate one + imul from the code generated for: + + long long test(long long X, long long Y) { return X*Y; } + + by using the EAX result from the mul. We should add a similar node for + DIVREM. + + //===---------------------------------------------------------------------===// + + This should be one DIV/IDIV instruction, not a libcall: + + unsigned test(unsigned long long X, unsigned Y) { + return X/Y; + } + + This can be done trivially with a custom legalizer. What about overflow + though? http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14224 + + //===---------------------------------------------------------------------===// + + Need to add support for rotate instructions. + + //===---------------------------------------------------------------------===// + + Some targets (e.g. athlons) prefer freep to fstp ST(0): + http://gcc.gnu.org/ml/gcc-patches/2004-04/msg00659.html + + //===---------------------------------------------------------------------===// + + This should use faddi on chips where it is profitable: + double foo(double P, int *I) { return P+*I; } + + //===---------------------------------------------------------------------===// + + The FP stackifier needs to be global. Also, it should handle simple permutates + to reduce number of shuffle instructions, e.g. turning: + + fld P -> fld Q + fld Q fld P + fxch + + or: + + fxch -> fucomi + fucomi jl X + jg X + + //===---------------------------------------------------------------------===// + + Improvements to the multiply -> shift/add algorithm: + http://gcc.gnu.org/ml/gcc-patches/2004-08/msg01590.html + + //===---------------------------------------------------------------------===// + + Improve code like this (occurs fairly frequently, e.g. in LLVM): + long long foo(int x) { return 1LL << x; } + + http://gcc.gnu.org/ml/gcc-patches/2004-09/msg01109.html + http://gcc.gnu.org/ml/gcc-patches/2004-09/msg01128.html + http://gcc.gnu.org/ml/gcc-patches/2004-09/msg01136.html + + Another useful one would be ~0ULL >> X and ~0ULL << X. + + //===---------------------------------------------------------------------===// + + Should support emission of the bswap instruction, probably by adding a new + DAG node for byte swapping. Also useful on PPC which has byte-swapping loads. + Index: llvm/lib/Target/X86/X86.h diff -u llvm/lib/Target/X86/X86.h:1.36 llvm/lib/Target/X86/X86.h:1.36.2.1 --- llvm/lib/Target/X86/X86.h:1.36 Thu Aug 18 18:53:15 2005 +++ llvm/lib/Target/X86/X86.h Wed Nov 16 12:32:45 2005 @@ -32,10 +32,16 @@ extern X86VectorEnum X86Vector; extern bool X86ScalarSSE; -/// createX86PatternInstructionSelector - This pass converts an LLVM function -/// into a machine code representation in a more aggressive way. +/// createX86ISelPattern - This pass converts an LLVM function into a +/// machine code representation using pattern matching and a machine +/// description file. /// -FunctionPass *createX86PatternInstructionSelector(TargetMachine &TM); +FunctionPass *createX86ISelPattern(TargetMachine &TM); + +/// createX86ISelDag - This pass converts a legalized DAG into a +/// X86-specific DAG, ready for instruction scheduling. +/// +FunctionPass *createX86ISelDag(TargetMachine &TM); /// createX86SSAPeepholeOptimizerPass - Create a pass to perform SSA-based X86 /// specific peephole optimizations. Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -c /dev/null llvm/lib/Target/X86/X86ISelLowering.cpp:1.1.2.2 *** /dev/null Wed Nov 16 12:32:57 2005 --- llvm/lib/Target/X86/X86ISelLowering.cpp Wed Nov 16 12:32:45 2005 *************** *** 0 **** --- 1,916 ---- + //===-- X86ISelLowering.h - X86 DAG Lowering Interface ----------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Chris Lattner and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file defines the interfaces that X86 uses to lower LLVM code into a + // selection DAG. + // + //===----------------------------------------------------------------------===// + + #include "X86.h" + #include "X86ISelLowering.h" + #include "X86TargetMachine.h" + #include "llvm/CallingConv.h" + #include "llvm/Function.h" + #include "llvm/CodeGen/MachineFunction.h" + #include "llvm/CodeGen/MachineFrameInfo.h" + #include "llvm/CodeGen/SelectionDAG.h" + #include "llvm/CodeGen/SSARegMap.h" + #include "llvm/Target/TargetOptions.h" + using namespace llvm; + + // FIXME: temporary. + #include "llvm/Support/CommandLine.h" + static cl::opt EnableFastCC("enable-x86-fastcc", cl::Hidden, + cl::desc("Enable fastcc on X86")); + + X86TargetLowering::X86TargetLowering(TargetMachine &TM) + : TargetLowering(TM) { + + // Set up the TargetLowering object. + + // X86 is weird, it always uses i8 for shift amounts and setcc results. + setShiftAmountType(MVT::i8); + setSetCCResultType(MVT::i8); + setSetCCResultContents(ZeroOrOneSetCCResult); + setShiftAmountFlavor(Mask); // shl X, 32 == shl X, 0 + + // Set up the register classes. + // FIXME: Eliminate these two classes when legalize can handle promotions + // well. + addRegisterClass(MVT::i1, X86::R8RegisterClass); + addRegisterClass(MVT::i8, X86::R8RegisterClass); + addRegisterClass(MVT::i16, X86::R16RegisterClass); + addRegisterClass(MVT::i32, X86::R32RegisterClass); + + // Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this + // operation. + setOperationAction(ISD::UINT_TO_FP , MVT::i1 , Promote); + setOperationAction(ISD::UINT_TO_FP , MVT::i8 , Promote); + setOperationAction(ISD::UINT_TO_FP , MVT::i16 , Promote); + setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Promote); + + // Promote i1/i8 SINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have + // this operation. + setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote); + setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote); + + if (!X86ScalarSSE) { + // We can handle SINT_TO_FP and FP_TO_SINT from/TO i64 even though i64 + // isn't legal. + setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom); + setOperationAction(ISD::FP_TO_SINT , MVT::i64 , Custom); + setOperationAction(ISD::FP_TO_SINT , MVT::i32 , Custom); + setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Custom); + } + + // Handle FP_TO_UINT by promoting the destination to a larger signed + // conversion. + setOperationAction(ISD::FP_TO_UINT , MVT::i1 , Promote); + setOperationAction(ISD::FP_TO_UINT , MVT::i8 , Promote); + setOperationAction(ISD::FP_TO_UINT , MVT::i16 , Promote); + + if (!X86ScalarSSE) + setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Promote); + + // Promote i1/i8 FP_TO_SINT to larger FP_TO_SINTS's, as X86 doesn't have + // this operation. + setOperationAction(ISD::FP_TO_SINT , MVT::i1 , Promote); + setOperationAction(ISD::FP_TO_SINT , MVT::i8 , Promote); + setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Promote); + + setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand); + setOperationAction(ISD::BRTWOWAY_CC , MVT::Other, Expand); + setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); + setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand); + setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); + setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand); + setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand); + setOperationAction(ISD::FREM , MVT::f64 , Expand); + setOperationAction(ISD::CTPOP , MVT::i8 , Expand); + setOperationAction(ISD::CTTZ , MVT::i8 , Expand); + setOperationAction(ISD::CTLZ , MVT::i8 , Expand); + setOperationAction(ISD::CTPOP , MVT::i16 , Expand); + setOperationAction(ISD::CTTZ , MVT::i16 , Expand); + setOperationAction(ISD::CTLZ , MVT::i16 , Expand); + setOperationAction(ISD::CTPOP , MVT::i32 , Expand); + setOperationAction(ISD::CTTZ , MVT::i32 , Expand); + setOperationAction(ISD::CTLZ , MVT::i32 , Expand); + + setOperationAction(ISD::READIO , MVT::i1 , Expand); + setOperationAction(ISD::READIO , MVT::i8 , Expand); + setOperationAction(ISD::READIO , MVT::i16 , Expand); + setOperationAction(ISD::READIO , MVT::i32 , Expand); + setOperationAction(ISD::WRITEIO , MVT::i1 , Expand); + setOperationAction(ISD::WRITEIO , MVT::i8 , Expand); + setOperationAction(ISD::WRITEIO , MVT::i16 , Expand); + setOperationAction(ISD::WRITEIO , MVT::i32 , Expand); + + // These should be promoted to a larger select which is supported. + setOperationAction(ISD::SELECT , MVT::i1 , Promote); + setOperationAction(ISD::SELECT , MVT::i8 , Promote); + + if (X86ScalarSSE) { + // Set up the FP register classes. + addRegisterClass(MVT::f32, X86::V4F4RegisterClass); + addRegisterClass(MVT::f64, X86::V2F8RegisterClass); + + // SSE has no load+extend ops + setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); + setOperationAction(ISD::ZEXTLOAD, MVT::f32, Expand); + + // SSE has no i16 to fp conversion, only i32 + setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote); + setOperationAction(ISD::FP_TO_SINT, MVT::i16, Promote); + + // Expand FP_TO_UINT into a select. + // FIXME: We would like to use a Custom expander here eventually to do + // the optimal thing for SSE vs. the default expansion in the legalizer. + setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Expand); + + // We don't support sin/cos/sqrt/fmod + setOperationAction(ISD::FSIN , MVT::f64, Expand); + setOperationAction(ISD::FCOS , MVT::f64, Expand); + setOperationAction(ISD::FABS , MVT::f64, Expand); + setOperationAction(ISD::FNEG , MVT::f64, Expand); + setOperationAction(ISD::FREM , MVT::f64, Expand); + setOperationAction(ISD::FSIN , MVT::f32, Expand); + setOperationAction(ISD::FCOS , MVT::f32, Expand); + setOperationAction(ISD::FABS , MVT::f32, Expand); + setOperationAction(ISD::FNEG , MVT::f32, Expand); + setOperationAction(ISD::FREM , MVT::f32, Expand); + + addLegalFPImmediate(+0.0); // xorps / xorpd + } else { + // Set up the FP register classes. + addRegisterClass(MVT::f64, X86::RFPRegisterClass); + + if (!UnsafeFPMath) { + setOperationAction(ISD::FSIN , MVT::f64 , Expand); + setOperationAction(ISD::FCOS , MVT::f64 , Expand); + } + + addLegalFPImmediate(+0.0); // FLD0 + addLegalFPImmediate(+1.0); // FLD1 + addLegalFPImmediate(-0.0); // FLD0/FCHS + addLegalFPImmediate(-1.0); // FLD1/FCHS + } + computeRegisterProperties(); + + maxStoresPerMemSet = 8; // For %llvm.memset -> sequence of stores + maxStoresPerMemCpy = 8; // For %llvm.memcpy -> sequence of stores + maxStoresPerMemMove = 8; // For %llvm.memmove -> sequence of stores + allowUnalignedMemoryAccesses = true; // x86 supports it! + } + + std::vector + X86TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { + if (F.getCallingConv() == CallingConv::Fast && EnableFastCC) + return LowerFastCCArguments(F, DAG); + return LowerCCCArguments(F, DAG); + } + + std::pair + X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, + bool isVarArg, unsigned CallingConv, + bool isTailCall, + SDOperand Callee, ArgListTy &Args, + SelectionDAG &DAG) { + assert((!isVarArg || CallingConv == CallingConv::C) && + "Only C takes varargs!"); + if (CallingConv == CallingConv::Fast && EnableFastCC) + return LowerFastCCCallTo(Chain, RetTy, isTailCall, Callee, Args, DAG); + return LowerCCCCallTo(Chain, RetTy, isVarArg, isTailCall, Callee, Args, DAG); + } + + //===----------------------------------------------------------------------===// + // C Calling Convention implementation + //===----------------------------------------------------------------------===// + + std::vector + X86TargetLowering::LowerCCCArguments(Function &F, SelectionDAG &DAG) { + std::vector ArgValues; + + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + + // Add DAG nodes to load the arguments... On entry to a function on the X86, + // the stack frame looks like this: + // + // [ESP] -- return address + // [ESP + 4] -- first argument (leftmost lexically) + // [ESP + 8] -- second argument, if first argument is four bytes in size + // ... + // + unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot + for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { + MVT::ValueType ObjectVT = getValueType(I->getType()); + unsigned ArgIncrement = 4; + unsigned ObjSize; + switch (ObjectVT) { + default: assert(0 && "Unhandled argument type!"); + case MVT::i1: + case MVT::i8: ObjSize = 1; break; + case MVT::i16: ObjSize = 2; break; + case MVT::i32: ObjSize = 4; break; + case MVT::i64: ObjSize = ArgIncrement = 8; break; + case MVT::f32: ObjSize = 4; break; + case MVT::f64: ObjSize = ArgIncrement = 8; break; + } + // Create the frame index object for this incoming parameter... + int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); + + // Create the SelectionDAG nodes corresponding to a load from this parameter + SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); + + // Don't codegen dead arguments. FIXME: remove this check when we can nuke + // dead loads. + SDOperand ArgValue; + if (!I->use_empty()) + ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN, + DAG.getSrcValue(NULL)); + else { + if (MVT::isInteger(ObjectVT)) + ArgValue = DAG.getConstant(0, ObjectVT); + else + ArgValue = DAG.getConstantFP(0, ObjectVT); + } + ArgValues.push_back(ArgValue); + + ArgOffset += ArgIncrement; // Move on to the next argument... + } + + // If the function takes variable number of arguments, make a frame index for + // the start of the first vararg value... for expansion of llvm.va_start. + if (F.isVarArg()) + VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset); + ReturnAddrIndex = 0; // No return address slot generated yet. + BytesToPopOnReturn = 0; // Callee pops nothing. + BytesCallerReserves = ArgOffset; + + // Finally, inform the code generator which regs we return values in. + switch (getValueType(F.getReturnType())) { + default: assert(0 && "Unknown type!"); + case MVT::isVoid: break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + MF.addLiveOut(X86::EAX); + break; + case MVT::i64: + MF.addLiveOut(X86::EAX); + MF.addLiveOut(X86::EDX); + break; + case MVT::f32: + case MVT::f64: + MF.addLiveOut(X86::ST0); + break; + } + return ArgValues; + } + + std::pair + X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy, + bool isVarArg, bool isTailCall, + SDOperand Callee, ArgListTy &Args, + SelectionDAG &DAG) { + // Count how many bytes are to be pushed on the stack. + unsigned NumBytes = 0; + + if (Args.empty()) { + // Save zero bytes. + Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, + DAG.getConstant(0, getPointerTy())); + } else { + for (unsigned i = 0, e = Args.size(); i != e; ++i) + switch (getValueType(Args[i].second)) { + default: assert(0 && "Unknown value type!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + case MVT::f32: + NumBytes += 4; + break; + case MVT::i64: + case MVT::f64: + NumBytes += 8; + break; + } + + Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, + DAG.getConstant(NumBytes, getPointerTy())); + + // Arguments go on the stack in reverse order, as specified by the ABI. + unsigned ArgOffset = 0; + SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(), + X86::ESP, MVT::i32); + std::vector Stores; + + for (unsigned i = 0, e = Args.size(); i != e; ++i) { + SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); + + switch (getValueType(Args[i].second)) { + default: assert(0 && "Unexpected ValueType for argument!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + // Promote the integer to 32 bits. If the input type is signed use a + // sign extend, otherwise use a zero extend. + if (Args[i].second->isSigned()) + Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first); + else + Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first); + + // FALL THROUGH + case MVT::i32: + case MVT::f32: + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff, + DAG.getSrcValue(NULL))); + ArgOffset += 4; + break; + case MVT::i64: + case MVT::f64: + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff, + DAG.getSrcValue(NULL))); + ArgOffset += 8; + break; + } + } + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores); + } + + std::vector RetVals; + MVT::ValueType RetTyVT = getValueType(RetTy); + RetVals.push_back(MVT::Other); + + // The result values produced have to be legal. Promote the result. + switch (RetTyVT) { + case MVT::isVoid: break; + default: + RetVals.push_back(RetTyVT); + break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + RetVals.push_back(MVT::i32); + break; + case MVT::f32: + if (X86ScalarSSE) + RetVals.push_back(MVT::f32); + else + RetVals.push_back(MVT::f64); + break; + case MVT::i64: + RetVals.push_back(MVT::i32); + RetVals.push_back(MVT::i32); + break; + } + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(Callee); + Ops.push_back(DAG.getConstant(NumBytes, getPointerTy())); + Ops.push_back(DAG.getConstant(0, getPointerTy())); + SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, + RetVals, Ops); + Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall); + + SDOperand ResultVal; + switch (RetTyVT) { + case MVT::isVoid: break; + default: + ResultVal = TheCall.getValue(1); + break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1)); + break; + case MVT::f32: + // FIXME: we would really like to remember that this FP_ROUND operation is + // okay to eliminate if we allow excess FP precision. + ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1)); + break; + case MVT::i64: + ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1), + TheCall.getValue(2)); + break; + } + + return std::make_pair(ResultVal, Chain); + } + + SDOperand + X86TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG) { + // vastart just stores the address of the VarArgsFrameIndex slot. + SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); + return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, + DAG.getSrcValue(VAListV)); + } + + + std::pair + X86TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, + Value *VAListV, const Type *ArgTy, + SelectionDAG &DAG) { + MVT::ValueType ArgVT = getValueType(ArgTy); + SDOperand Val = DAG.getLoad(MVT::i32, Chain, + VAListP, DAG.getSrcValue(VAListV)); + SDOperand Result = DAG.getLoad(ArgVT, Chain, Val, + DAG.getSrcValue(NULL)); + unsigned Amt; + if (ArgVT == MVT::i32) + Amt = 4; + else { + assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && + "Other types should have been promoted for varargs!"); + Amt = 8; + } + Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val, + DAG.getConstant(Amt, Val.getValueType())); + Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, + Val, VAListP, DAG.getSrcValue(VAListV)); + return std::make_pair(Result, Chain); + } + + //===----------------------------------------------------------------------===// + // Fast Calling Convention implementation + //===----------------------------------------------------------------------===// + // + // The X86 'fast' calling convention passes up to two integer arguments in + // registers (an appropriate portion of EAX/EDX), passes arguments in C order, + // and requires that the callee pop its arguments off the stack (allowing proper + // tail calls), and has the same return value conventions as C calling convs. + // + // This calling convention always arranges for the callee pop value to be 8n+4 + // bytes, which is needed for tail recursion elimination and stack alignment + // reasons. + // + // Note that this can be enhanced in the future to pass fp vals in registers + // (when we have a global fp allocator) and do other tricks. + // + + /// AddLiveIn - This helper function adds the specified physical register to the + /// MachineFunction as a live in value. It also creates a corresponding virtual + /// register for it. + static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg, + TargetRegisterClass *RC) { + assert(RC->contains(PReg) && "Not the correct regclass!"); + unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC); + MF.addLiveIn(PReg, VReg); + return VReg; + } + + + std::vector + X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) { + std::vector ArgValues; + + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + + // Add DAG nodes to load the arguments... On entry to a function the stack + // frame looks like this: + // + // [ESP] -- return address + // [ESP + 4] -- first nonreg argument (leftmost lexically) + // [ESP + 8] -- second nonreg argument, if first argument is 4 bytes in size + // ... + unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot + + // Keep track of the number of integer regs passed so far. This can be either + // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both + // used). + unsigned NumIntRegs = 0; + + for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { + MVT::ValueType ObjectVT = getValueType(I->getType()); + unsigned ArgIncrement = 4; + unsigned ObjSize = 0; + SDOperand ArgValue; + + switch (ObjectVT) { + default: assert(0 && "Unhandled argument type!"); + case MVT::i1: + case MVT::i8: + if (NumIntRegs < 2) { + if (!I->use_empty()) { + unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DL : X86::AL, + X86::R8RegisterClass); + ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i8); + DAG.setRoot(ArgValue.getValue(1)); + } + ++NumIntRegs; + break; + } + + ObjSize = 1; + break; + case MVT::i16: + if (NumIntRegs < 2) { + if (!I->use_empty()) { + unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DX : X86::AX, + X86::R16RegisterClass); + ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i16); + DAG.setRoot(ArgValue.getValue(1)); + } + ++NumIntRegs; + break; + } + ObjSize = 2; + break; + case MVT::i32: + if (NumIntRegs < 2) { + if (!I->use_empty()) { + unsigned VReg = AddLiveIn(MF,NumIntRegs ? X86::EDX : X86::EAX, + X86::R32RegisterClass); + ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32); + DAG.setRoot(ArgValue.getValue(1)); + } + ++NumIntRegs; + break; + } + ObjSize = 4; + break; + case MVT::i64: + if (NumIntRegs == 0) { + if (!I->use_empty()) { + unsigned BotReg = AddLiveIn(MF, X86::EAX, X86::R32RegisterClass); + unsigned TopReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass); + + SDOperand Low = DAG.getCopyFromReg(DAG.getRoot(), BotReg, MVT::i32); + SDOperand Hi = DAG.getCopyFromReg(Low.getValue(1), TopReg, MVT::i32); + DAG.setRoot(Hi.getValue(1)); + + ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Low, Hi); + } + NumIntRegs = 2; + break; + } else if (NumIntRegs == 1) { + if (!I->use_empty()) { + unsigned BotReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass); + SDOperand Low = DAG.getCopyFromReg(DAG.getRoot(), BotReg, MVT::i32); + DAG.setRoot(Low.getValue(1)); + + // Load the high part from memory. + // Create the frame index object for this incoming parameter... + int FI = MFI->CreateFixedObject(4, ArgOffset); + SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); + SDOperand Hi = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN, + DAG.getSrcValue(NULL)); + ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Low, Hi); + } + ArgOffset += 4; + NumIntRegs = 2; + break; + } + ObjSize = ArgIncrement = 8; + break; + case MVT::f32: ObjSize = 4; break; + case MVT::f64: ObjSize = ArgIncrement = 8; break; + } + + // Don't codegen dead arguments. FIXME: remove this check when we can nuke + // dead loads. + if (ObjSize && !I->use_empty()) { + // Create the frame index object for this incoming parameter... + int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); + + // Create the SelectionDAG nodes corresponding to a load from this + // parameter. + SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); + + ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN, + DAG.getSrcValue(NULL)); + } else if (ArgValue.Val == 0) { + if (MVT::isInteger(ObjectVT)) + ArgValue = DAG.getConstant(0, ObjectVT); + else + ArgValue = DAG.getConstantFP(0, ObjectVT); + } + ArgValues.push_back(ArgValue); + + if (ObjSize) + ArgOffset += ArgIncrement; // Move on to the next argument. + } + + // Make sure the instruction takes 8n+4 bytes to make sure the start of the + // arguments and the arguments after the retaddr has been pushed are aligned. + if ((ArgOffset & 7) == 0) + ArgOffset += 4; + + VarArgsFrameIndex = 0xAAAAAAA; // fastcc functions can't have varargs. + ReturnAddrIndex = 0; // No return address slot generated yet. + BytesToPopOnReturn = ArgOffset; // Callee pops all stack arguments. + BytesCallerReserves = 0; + + // Finally, inform the code generator which regs we return values in. + switch (getValueType(F.getReturnType())) { + default: assert(0 && "Unknown type!"); + case MVT::isVoid: break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + MF.addLiveOut(X86::EAX); + break; + case MVT::i64: + MF.addLiveOut(X86::EAX); + MF.addLiveOut(X86::EDX); + break; + case MVT::f32: + case MVT::f64: + MF.addLiveOut(X86::ST0); + break; + } + return ArgValues; + } + + std::pair + X86TargetLowering::LowerFastCCCallTo(SDOperand Chain, const Type *RetTy, + bool isTailCall, SDOperand Callee, + ArgListTy &Args, SelectionDAG &DAG) { + // Count how many bytes are to be pushed on the stack. + unsigned NumBytes = 0; + + // Keep track of the number of integer regs passed so far. This can be either + // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both + // used). + unsigned NumIntRegs = 0; + + for (unsigned i = 0, e = Args.size(); i != e; ++i) + switch (getValueType(Args[i].second)) { + default: assert(0 && "Unknown value type!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + if (NumIntRegs < 2) { + ++NumIntRegs; + break; + } + // fall through + case MVT::f32: + NumBytes += 4; + break; + case MVT::i64: + if (NumIntRegs == 0) { + NumIntRegs = 2; + break; + } else if (NumIntRegs == 1) { + NumIntRegs = 2; + NumBytes += 4; + break; + } + + // fall through + case MVT::f64: + NumBytes += 8; + break; + } + + // Make sure the instruction takes 8n+4 bytes to make sure the start of the + // arguments and the arguments after the retaddr has been pushed are aligned. + if ((NumBytes & 7) == 0) + NumBytes += 4; + + Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, + DAG.getConstant(NumBytes, getPointerTy())); + + // Arguments go on the stack in reverse order, as specified by the ABI. + unsigned ArgOffset = 0; + SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(), + X86::ESP, MVT::i32); + NumIntRegs = 0; + std::vector Stores; + std::vector RegValuesToPass; + for (unsigned i = 0, e = Args.size(); i != e; ++i) { + switch (getValueType(Args[i].second)) { + default: assert(0 && "Unexpected ValueType for argument!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + if (NumIntRegs < 2) { + RegValuesToPass.push_back(Args[i].first); + ++NumIntRegs; + break; + } + // Fall through + case MVT::f32: { + SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff, + DAG.getSrcValue(NULL))); + ArgOffset += 4; + break; + } + case MVT::i64: + if (NumIntRegs < 2) { // Can pass part of it in regs? + SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, + Args[i].first, DAG.getConstant(1, MVT::i32)); + SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, + Args[i].first, DAG.getConstant(0, MVT::i32)); + RegValuesToPass.push_back(Lo); + ++NumIntRegs; + if (NumIntRegs < 2) { // Pass both parts in regs? + RegValuesToPass.push_back(Hi); + ++NumIntRegs; + } else { + // Pass the high part in memory. + SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Hi, PtrOff, DAG.getSrcValue(NULL))); + ArgOffset += 4; + } + break; + } + // Fall through + case MVT::f64: + SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); + Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Args[i].first, PtrOff, + DAG.getSrcValue(NULL))); + ArgOffset += 8; + break; + } + } + if (!Stores.empty()) + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores); + + // Make sure the instruction takes 8n+4 bytes to make sure the start of the + // arguments and the arguments after the retaddr has been pushed are aligned. + if ((ArgOffset & 7) == 0) + ArgOffset += 4; + + std::vector RetVals; + MVT::ValueType RetTyVT = getValueType(RetTy); + + RetVals.push_back(MVT::Other); + + // The result values produced have to be legal. Promote the result. + switch (RetTyVT) { + case MVT::isVoid: break; + default: + RetVals.push_back(RetTyVT); + break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + RetVals.push_back(MVT::i32); + break; + case MVT::f32: + if (X86ScalarSSE) + RetVals.push_back(MVT::f32); + else + RetVals.push_back(MVT::f64); + break; + case MVT::i64: + RetVals.push_back(MVT::i32); + RetVals.push_back(MVT::i32); + break; + } + + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(Callee); + Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy())); + // Callee pops all arg values on the stack. + Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy())); + + // Pass register arguments as needed. + Ops.insert(Ops.end(), RegValuesToPass.begin(), RegValuesToPass.end()); + + SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, + RetVals, Ops); + Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall); + + SDOperand ResultVal; + switch (RetTyVT) { + case MVT::isVoid: break; + default: + ResultVal = TheCall.getValue(1); + break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1)); + break; + case MVT::f32: + // FIXME: we would really like to remember that this FP_ROUND operation is + // okay to eliminate if we allow excess FP precision. + ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1)); + break; + case MVT::i64: + ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1), + TheCall.getValue(2)); + break; + } + + return std::make_pair(ResultVal, Chain); + } + + SDOperand X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) { + if (ReturnAddrIndex == 0) { + // Set up a frame object for the return address. + MachineFunction &MF = DAG.getMachineFunction(); + ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(4, -4); + } + + return DAG.getFrameIndex(ReturnAddrIndex, MVT::i32); + } + + + + std::pair X86TargetLowering:: + LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, + SelectionDAG &DAG) { + SDOperand Result; + if (Depth) // Depths > 0 not supported yet! + Result = DAG.getConstant(0, getPointerTy()); + else { + SDOperand RetAddrFI = getReturnAddressFrameIndex(DAG); + if (!isFrameAddress) + // Just load the return address + Result = DAG.getLoad(MVT::i32, DAG.getEntryNode(), RetAddrFI, + DAG.getSrcValue(NULL)); + else + Result = DAG.getNode(ISD::SUB, MVT::i32, RetAddrFI, + DAG.getConstant(4, MVT::i32)); + } + return std::make_pair(Result, Chain); + } + + //===----------------------------------------------------------------------===// + // X86 Custom Lowering Hooks + //===----------------------------------------------------------------------===// + + /// LowerOperation - Provide custom lowering hooks for some operations. + /// + SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { + switch (Op.getOpcode()) { + default: assert(0 && "Should not custom lower this!"); + case ISD::SINT_TO_FP: { + assert(Op.getValueType() == MVT::f64 && + Op.getOperand(0).getValueType() == MVT::i64 && + "Unknown SINT_TO_FP to lower!"); + // We lower sint64->FP into a store to a temporary stack slot, followed by a + // FILD64m node. + MachineFunction &MF = DAG.getMachineFunction(); + int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8); + SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); + SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), + Op.getOperand(0), StackSlot, DAG.getSrcValue(NULL)); + std::vector RTs; + RTs.push_back(MVT::f64); + RTs.push_back(MVT::Other); + std::vector Ops; + Ops.push_back(Store); + Ops.push_back(StackSlot); + return DAG.getNode(X86ISD::FILD64m, RTs, Ops); + } + case ISD::FP_TO_SINT: { + assert(Op.getValueType() <= MVT::i64 && Op.getValueType() >= MVT::i16 && + Op.getOperand(0).getValueType() == MVT::f64 && + "Unknown FP_TO_SINT to lower!"); + // We lower FP->sint64 into FISTP64, followed by a load, all to a temporary + // stack slot. + MachineFunction &MF = DAG.getMachineFunction(); + unsigned MemSize = MVT::getSizeInBits(Op.getValueType())/8; + int SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize); + SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); + + unsigned Opc; + switch (Op.getValueType()) { + default: assert(0 && "Invalid FP_TO_SINT to lower!"); + case MVT::i16: Opc = X86ISD::FP_TO_INT16_IN_MEM; break; + case MVT::i32: Opc = X86ISD::FP_TO_INT32_IN_MEM; break; + case MVT::i64: Opc = X86ISD::FP_TO_INT64_IN_MEM; break; + } + + // Build the FP_TO_INT*_IN_MEM + std::vector Ops; + Ops.push_back(DAG.getEntryNode()); + Ops.push_back(Op.getOperand(0)); + Ops.push_back(StackSlot); + SDOperand FIST = DAG.getNode(Opc, MVT::Other, Ops); + + // Load the result. + return DAG.getLoad(Op.getValueType(), FIST, StackSlot, + DAG.getSrcValue(NULL)); + } + } + } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -c /dev/null llvm/lib/Target/X86/X86ISelLowering.h:1.1.2.2 *** /dev/null Wed Nov 16 12:32:57 2005 --- llvm/lib/Target/X86/X86ISelLowering.h Wed Nov 16 12:32:45 2005 *************** *** 0 **** --- 1,131 ---- + //===-- X86ISelLowering.h - X86 DAG Lowering Interface ----------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Chris Lattner and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file defines the interfaces that X86 uses to lower LLVM code into a + // selection DAG. + // + //===----------------------------------------------------------------------===// + + #ifndef X86ISELLOWERING_H + #define X86ISELLOWERING_H + + #include "llvm/Target/TargetLowering.h" + #include "llvm/CodeGen/SelectionDAG.h" + + namespace llvm { + // X86 Specific DAG Nodes + namespace X86ISD { + enum NodeType { + // Start the numbering where the builtin ops leave off. + FIRST_NUMBER = ISD::BUILTIN_OP_END, + + /// FILD64m - This instruction implements SINT_TO_FP with a + /// 64-bit source in memory and a FP reg result. This corresponds to + /// the X86::FILD64m instruction. It has two inputs (token chain and + /// address) and two outputs (FP value and token chain). + FILD64m, + + /// FP_TO_INT*_IN_MEM - This instruction implements FP_TO_SINT with the + /// integer destination in memory and a FP reg source. This corresponds + /// to the X86::FIST*m instructions and the rounding mode change stuff. It + /// has two inputs (token chain and address) and two outputs (FP value and + /// token chain). + FP_TO_INT16_IN_MEM, + FP_TO_INT32_IN_MEM, + FP_TO_INT64_IN_MEM, + + /// CALL/TAILCALL - These operations represent an abstract X86 call + /// instruction, which includes a bunch of information. In particular the + /// operands of these node are: + /// + /// #0 - The incoming token chain + /// #1 - The callee + /// #2 - The number of arg bytes the caller pushes on the stack. + /// #3 - The number of arg bytes the callee pops off the stack. + /// #4 - The value to pass in AL/AX/EAX (optional) + /// #5 - The value to pass in DL/DX/EDX (optional) + /// + /// The result values of these nodes are: + /// + /// #0 - The outgoing token chain + /// #1 - The first register result value (optional) + /// #2 - The second register result value (optional) + /// + /// The CALL vs TAILCALL distinction boils down to whether the callee is + /// known not to modify the caller's stack frame, as is standard with + /// LLVM. + CALL, + TAILCALL, + }; + } + + //===----------------------------------------------------------------------===// + // X86TargetLowering - X86 Implementation of the TargetLowering interface + class X86TargetLowering : public TargetLowering { + int VarArgsFrameIndex; // FrameIndex for start of varargs area. + int ReturnAddrIndex; // FrameIndex for return slot. + int BytesToPopOnReturn; // Number of arg bytes ret should pop. + int BytesCallerReserves; // Number of arg bytes caller makes. + public: + X86TargetLowering(TargetMachine &TM); + + // Return the number of bytes that a function should pop when it returns (in + // addition to the space used by the return address). + // + unsigned getBytesToPopOnReturn() const { return BytesToPopOnReturn; } + + // Return the number of bytes that the caller reserves for arguments passed + // to this function. + unsigned getBytesCallerReserves() const { return BytesCallerReserves; } + + /// LowerOperation - Provide custom lowering hooks for some operations. + /// + virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); + + /// LowerArguments - This hook must be implemented to indicate how we should + /// lower the arguments for the specified function, into the specified DAG. + virtual std::vector + LowerArguments(Function &F, SelectionDAG &DAG); + + /// LowerCallTo - This hook lowers an abstract call to a function into an + /// actual call. + virtual std::pair + LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, unsigned CC, + bool isTailCall, SDOperand Callee, ArgListTy &Args, + SelectionDAG &DAG); + + virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, + Value *VAListV, SelectionDAG &DAG); + virtual std::pair + LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, + const Type *ArgTy, SelectionDAG &DAG); + + virtual std::pair + LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, + SelectionDAG &DAG); + + SDOperand getReturnAddressFrameIndex(SelectionDAG &DAG); + + private: + // C Calling Convention implementation. + std::vector LowerCCCArguments(Function &F, SelectionDAG &DAG); + std::pair + LowerCCCCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, + bool isTailCall, + SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); + + // Fast Calling Convention implementation. + std::vector LowerFastCCArguments(Function &F, SelectionDAG &DAG); + std::pair + LowerFastCCCallTo(SDOperand Chain, const Type *RetTy, bool isTailCall, + SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); + }; + } + + #endif // X86ISELLOWERING_H Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.183 llvm/lib/Target/X86/X86ISelPattern.cpp:1.183.2.1 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.183 Sat Oct 15 17:08:02 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Wed Nov 16 12:32:45 2005 @@ -15,6 +15,7 @@ #include "X86InstrBuilder.h" #include "X86RegisterInfo.h" #include "X86Subtarget.h" +#include "X86ISelLowering.h" #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" @@ -36,1006 +37,6 @@ #include using namespace llvm; -// FIXME: temporary. -#include "llvm/Support/CommandLine.h" -static cl::opt EnableFastCC("enable-x86-fastcc", cl::Hidden, - cl::desc("Enable fastcc on X86")); - -namespace { - // X86 Specific DAG Nodes - namespace X86ISD { - enum NodeType { - // Start the numbering where the builtin ops leave off. - FIRST_NUMBER = ISD::BUILTIN_OP_END, - - /// FILD64m - This instruction implements SINT_TO_FP with a - /// 64-bit source in memory and a FP reg result. This corresponds to - /// the X86::FILD64m instruction. It has two inputs (token chain and - /// address) and two outputs (FP value and token chain). - FILD64m, - - /// FP_TO_INT*_IN_MEM - This instruction implements FP_TO_SINT with the - /// integer destination in memory and a FP reg source. This corresponds - /// to the X86::FIST*m instructions and the rounding mode change stuff. It - /// has two inputs (token chain and address) and two outputs (FP value and - /// token chain). - FP_TO_INT16_IN_MEM, - FP_TO_INT32_IN_MEM, - FP_TO_INT64_IN_MEM, - - /// CALL/TAILCALL - These operations represent an abstract X86 call - /// instruction, which includes a bunch of information. In particular the - /// operands of these node are: - /// - /// #0 - The incoming token chain - /// #1 - The callee - /// #2 - The number of arg bytes the caller pushes on the stack. - /// #3 - The number of arg bytes the callee pops off the stack. - /// #4 - The value to pass in AL/AX/EAX (optional) - /// #5 - The value to pass in DL/DX/EDX (optional) - /// - /// The result values of these nodes are: - /// - /// #0 - The outgoing token chain - /// #1 - The first register result value (optional) - /// #2 - The second register result value (optional) - /// - /// The CALL vs TAILCALL distinction boils down to whether the callee is - /// known not to modify the caller's stack frame, as is standard with - /// LLVM. - CALL, - TAILCALL, - }; - } -} - -//===----------------------------------------------------------------------===// -// X86TargetLowering - X86 Implementation of the TargetLowering interface -namespace { - class X86TargetLowering : public TargetLowering { - int VarArgsFrameIndex; // FrameIndex for start of varargs area. - int ReturnAddrIndex; // FrameIndex for return slot. - int BytesToPopOnReturn; // Number of arg bytes ret should pop. - int BytesCallerReserves; // Number of arg bytes caller makes. - public: - X86TargetLowering(TargetMachine &TM) : TargetLowering(TM) { - // Set up the TargetLowering object. - - // X86 is weird, it always uses i8 for shift amounts and setcc results. - setShiftAmountType(MVT::i8); - setSetCCResultType(MVT::i8); - setSetCCResultContents(ZeroOrOneSetCCResult); - setShiftAmountFlavor(Mask); // shl X, 32 == shl X, 0 - - // Set up the register classes. - // FIXME: Eliminate these two classes when legalize can handle promotions - // well. - addRegisterClass(MVT::i1, X86::R8RegisterClass); - addRegisterClass(MVT::i8, X86::R8RegisterClass); - addRegisterClass(MVT::i16, X86::R16RegisterClass); - addRegisterClass(MVT::i32, X86::R32RegisterClass); - - // Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this - // operation. - setOperationAction(ISD::UINT_TO_FP , MVT::i1 , Promote); - setOperationAction(ISD::UINT_TO_FP , MVT::i8 , Promote); - setOperationAction(ISD::UINT_TO_FP , MVT::i16 , Promote); - setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Promote); - - // Promote i1/i8 SINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have - // this operation. - setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote); - setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote); - - if (!X86ScalarSSE) { - // We can handle SINT_TO_FP and FP_TO_SINT from/TO i64 even though i64 - // isn't legal. - setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom); - setOperationAction(ISD::FP_TO_SINT , MVT::i64 , Custom); - setOperationAction(ISD::FP_TO_SINT , MVT::i32 , Custom); - setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Custom); - } - - // Handle FP_TO_UINT by promoting the destination to a larger signed - // conversion. - setOperationAction(ISD::FP_TO_UINT , MVT::i1 , Promote); - setOperationAction(ISD::FP_TO_UINT , MVT::i8 , Promote); - setOperationAction(ISD::FP_TO_UINT , MVT::i16 , Promote); - - if (!X86ScalarSSE) - setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Promote); - - // Promote i1/i8 FP_TO_SINT to larger FP_TO_SINTS's, as X86 doesn't have - // this operation. - setOperationAction(ISD::FP_TO_SINT , MVT::i1 , Promote); - setOperationAction(ISD::FP_TO_SINT , MVT::i8 , Promote); - setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Promote); - - setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand); - setOperationAction(ISD::BRTWOWAY_CC , MVT::Other, Expand); - setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); - setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand); - setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); - setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand); - setOperationAction(ISD::SEXTLOAD , MVT::i1 , Expand); - setOperationAction(ISD::FREM , MVT::f64 , Expand); - setOperationAction(ISD::CTPOP , MVT::i8 , Expand); - setOperationAction(ISD::CTTZ , MVT::i8 , Expand); - setOperationAction(ISD::CTLZ , MVT::i8 , Expand); - setOperationAction(ISD::CTPOP , MVT::i16 , Expand); - setOperationAction(ISD::CTTZ , MVT::i16 , Expand); - setOperationAction(ISD::CTLZ , MVT::i16 , Expand); - setOperationAction(ISD::CTPOP , MVT::i32 , Expand); - setOperationAction(ISD::CTTZ , MVT::i32 , Expand); - setOperationAction(ISD::CTLZ , MVT::i32 , Expand); - - setOperationAction(ISD::READIO , MVT::i1 , Expand); - setOperationAction(ISD::READIO , MVT::i8 , Expand); - setOperationAction(ISD::READIO , MVT::i16 , Expand); - setOperationAction(ISD::READIO , MVT::i32 , Expand); - setOperationAction(ISD::WRITEIO , MVT::i1 , Expand); - setOperationAction(ISD::WRITEIO , MVT::i8 , Expand); - setOperationAction(ISD::WRITEIO , MVT::i16 , Expand); - setOperationAction(ISD::WRITEIO , MVT::i32 , Expand); - - // These should be promoted to a larger select which is supported. - setOperationAction(ISD::SELECT , MVT::i1 , Promote); - setOperationAction(ISD::SELECT , MVT::i8 , Promote); - - if (X86ScalarSSE) { - // Set up the FP register classes. - addRegisterClass(MVT::f32, X86::V4F4RegisterClass); - addRegisterClass(MVT::f64, X86::V2F8RegisterClass); - - // SSE has no load+extend ops - setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); - setOperationAction(ISD::ZEXTLOAD, MVT::f32, Expand); - - // SSE has no i16 to fp conversion, only i32 - setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote); - setOperationAction(ISD::FP_TO_SINT, MVT::i16, Promote); - - // Expand FP_TO_UINT into a select. - // FIXME: We would like to use a Custom expander here eventually to do - // the optimal thing for SSE vs. the default expansion in the legalizer. - setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Expand); - - // We don't support sin/cos/sqrt/fmod - setOperationAction(ISD::FSIN , MVT::f64, Expand); - setOperationAction(ISD::FCOS , MVT::f64, Expand); - setOperationAction(ISD::FABS , MVT::f64, Expand); - setOperationAction(ISD::FNEG , MVT::f64, Expand); - setOperationAction(ISD::FREM , MVT::f64, Expand); - setOperationAction(ISD::FSIN , MVT::f32, Expand); - setOperationAction(ISD::FCOS , MVT::f32, Expand); - setOperationAction(ISD::FABS , MVT::f32, Expand); - setOperationAction(ISD::FNEG , MVT::f32, Expand); - setOperationAction(ISD::FREM , MVT::f32, Expand); - - addLegalFPImmediate(+0.0); // xorps / xorpd - } else { - // Set up the FP register classes. - addRegisterClass(MVT::f64, X86::RFPRegisterClass); - - if (!UnsafeFPMath) { - setOperationAction(ISD::FSIN , MVT::f64 , Expand); - setOperationAction(ISD::FCOS , MVT::f64 , Expand); - } - - addLegalFPImmediate(+0.0); // FLD0 - addLegalFPImmediate(+1.0); // FLD1 - addLegalFPImmediate(-0.0); // FLD0/FCHS - addLegalFPImmediate(-1.0); // FLD1/FCHS - } - computeRegisterProperties(); - - maxStoresPerMemSet = 8; // For %llvm.memset -> sequence of stores - maxStoresPerMemCpy = 8; // For %llvm.memcpy -> sequence of stores - maxStoresPerMemMove = 8; // For %llvm.memmove -> sequence of stores - allowUnalignedMemoryAccesses = true; // x86 supports it! - } - - // Return the number of bytes that a function should pop when it returns (in - // addition to the space used by the return address). - // - unsigned getBytesToPopOnReturn() const { return BytesToPopOnReturn; } - - // Return the number of bytes that the caller reserves for arguments passed - // to this function. - unsigned getBytesCallerReserves() const { return BytesCallerReserves; } - - /// LowerOperation - Provide custom lowering hooks for some operations. - /// - virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); - - /// LowerArguments - This hook must be implemented to indicate how we should - /// lower the arguments for the specified function, into the specified DAG. - virtual std::vector - LowerArguments(Function &F, SelectionDAG &DAG); - - /// LowerCallTo - This hook lowers an abstract call to a function into an - /// actual call. - virtual std::pair - LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, unsigned CC, - bool isTailCall, SDOperand Callee, ArgListTy &Args, - SelectionDAG &DAG); - - virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG); - virtual std::pair - LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG); - - virtual std::pair - LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, - SelectionDAG &DAG); - - SDOperand getReturnAddressFrameIndex(SelectionDAG &DAG); - - private: - // C Calling Convention implementation. - std::vector LowerCCCArguments(Function &F, SelectionDAG &DAG); - std::pair - LowerCCCCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, - bool isTailCall, - SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); - - // Fast Calling Convention implementation. - std::vector LowerFastCCArguments(Function &F, SelectionDAG &DAG); - std::pair - LowerFastCCCallTo(SDOperand Chain, const Type *RetTy, bool isTailCall, - SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); - }; -} - -std::vector -X86TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { - if (F.getCallingConv() == CallingConv::Fast && EnableFastCC) - return LowerFastCCArguments(F, DAG); - return LowerCCCArguments(F, DAG); -} - -std::pair -X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, - bool isVarArg, unsigned CallingConv, - bool isTailCall, - SDOperand Callee, ArgListTy &Args, - SelectionDAG &DAG) { - assert((!isVarArg || CallingConv == CallingConv::C) && - "Only C takes varargs!"); - if (CallingConv == CallingConv::Fast && EnableFastCC) - return LowerFastCCCallTo(Chain, RetTy, isTailCall, Callee, Args, DAG); - return LowerCCCCallTo(Chain, RetTy, isVarArg, isTailCall, Callee, Args, DAG); -} - -//===----------------------------------------------------------------------===// -// C Calling Convention implementation -//===----------------------------------------------------------------------===// - -std::vector -X86TargetLowering::LowerCCCArguments(Function &F, SelectionDAG &DAG) { - std::vector ArgValues; - - MachineFunction &MF = DAG.getMachineFunction(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - - // Add DAG nodes to load the arguments... On entry to a function on the X86, - // the stack frame looks like this: - // - // [ESP] -- return address - // [ESP + 4] -- first argument (leftmost lexically) - // [ESP + 8] -- second argument, if first argument is four bytes in size - // ... - // - unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot - for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { - MVT::ValueType ObjectVT = getValueType(I->getType()); - unsigned ArgIncrement = 4; - unsigned ObjSize; - switch (ObjectVT) { - default: assert(0 && "Unhandled argument type!"); - case MVT::i1: - case MVT::i8: ObjSize = 1; break; - case MVT::i16: ObjSize = 2; break; - case MVT::i32: ObjSize = 4; break; - case MVT::i64: ObjSize = ArgIncrement = 8; break; - case MVT::f32: ObjSize = 4; break; - case MVT::f64: ObjSize = ArgIncrement = 8; break; - } - // Create the frame index object for this incoming parameter... - int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); - - // Create the SelectionDAG nodes corresponding to a load from this parameter - SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); - - // Don't codegen dead arguments. FIXME: remove this check when we can nuke - // dead loads. - SDOperand ArgValue; - if (!I->use_empty()) - ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN, - DAG.getSrcValue(NULL)); - else { - if (MVT::isInteger(ObjectVT)) - ArgValue = DAG.getConstant(0, ObjectVT); - else - ArgValue = DAG.getConstantFP(0, ObjectVT); - } - ArgValues.push_back(ArgValue); - - ArgOffset += ArgIncrement; // Move on to the next argument... - } - - // If the function takes variable number of arguments, make a frame index for - // the start of the first vararg value... for expansion of llvm.va_start. - if (F.isVarArg()) - VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset); - ReturnAddrIndex = 0; // No return address slot generated yet. - BytesToPopOnReturn = 0; // Callee pops nothing. - BytesCallerReserves = ArgOffset; - - // Finally, inform the code generator which regs we return values in. - switch (getValueType(F.getReturnType())) { - default: assert(0 && "Unknown type!"); - case MVT::isVoid: break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - MF.addLiveOut(X86::EAX); - break; - case MVT::i64: - MF.addLiveOut(X86::EAX); - MF.addLiveOut(X86::EDX); - break; - case MVT::f32: - case MVT::f64: - MF.addLiveOut(X86::ST0); - break; - } - return ArgValues; -} - -std::pair -X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy, - bool isVarArg, bool isTailCall, - SDOperand Callee, ArgListTy &Args, - SelectionDAG &DAG) { - // Count how many bytes are to be pushed on the stack. - unsigned NumBytes = 0; - - if (Args.empty()) { - // Save zero bytes. - Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, - DAG.getConstant(0, getPointerTy())); - } else { - for (unsigned i = 0, e = Args.size(); i != e; ++i) - switch (getValueType(Args[i].second)) { - default: assert(0 && "Unknown value type!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::f32: - NumBytes += 4; - break; - case MVT::i64: - case MVT::f64: - NumBytes += 8; - break; - } - - Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, - DAG.getConstant(NumBytes, getPointerTy())); - - // Arguments go on the stack in reverse order, as specified by the ABI. - unsigned ArgOffset = 0; - SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(), - X86::ESP, MVT::i32); - std::vector Stores; - - for (unsigned i = 0, e = Args.size(); i != e; ++i) { - SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); - - switch (getValueType(Args[i].second)) { - default: assert(0 && "Unexpected ValueType for argument!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - // Promote the integer to 32 bits. If the input type is signed use a - // sign extend, otherwise use a zero extend. - if (Args[i].second->isSigned()) - Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first); - else - Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first); - - // FALL THROUGH - case MVT::i32: - case MVT::f32: - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); - ArgOffset += 4; - break; - case MVT::i64: - case MVT::f64: - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); - ArgOffset += 8; - break; - } - } - Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores); - } - - std::vector RetVals; - MVT::ValueType RetTyVT = getValueType(RetTy); - RetVals.push_back(MVT::Other); - - // The result values produced have to be legal. Promote the result. - switch (RetTyVT) { - case MVT::isVoid: break; - default: - RetVals.push_back(RetTyVT); - break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - RetVals.push_back(MVT::i32); - break; - case MVT::f32: - if (X86ScalarSSE) - RetVals.push_back(MVT::f32); - else - RetVals.push_back(MVT::f64); - break; - case MVT::i64: - RetVals.push_back(MVT::i32); - RetVals.push_back(MVT::i32); - break; - } - std::vector Ops; - Ops.push_back(Chain); - Ops.push_back(Callee); - Ops.push_back(DAG.getConstant(NumBytes, getPointerTy())); - Ops.push_back(DAG.getConstant(0, getPointerTy())); - SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, - RetVals, Ops); - Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall); - - SDOperand ResultVal; - switch (RetTyVT) { - case MVT::isVoid: break; - default: - ResultVal = TheCall.getValue(1); - break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1)); - break; - case MVT::f32: - // FIXME: we would really like to remember that this FP_ROUND operation is - // okay to eliminate if we allow excess FP precision. - ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1)); - break; - case MVT::i64: - ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1), - TheCall.getValue(2)); - break; - } - - return std::make_pair(ResultVal, Chain); -} - -SDOperand -X86TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG &DAG) { - // vastart just stores the address of the VarArgsFrameIndex slot. - SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); - return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, - DAG.getSrcValue(VAListV)); -} - - -std::pair -X86TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, - Value *VAListV, const Type *ArgTy, - SelectionDAG &DAG) { - MVT::ValueType ArgVT = getValueType(ArgTy); - SDOperand Val = DAG.getLoad(MVT::i32, Chain, - VAListP, DAG.getSrcValue(VAListV)); - SDOperand Result = DAG.getLoad(ArgVT, Chain, Val, - DAG.getSrcValue(NULL)); - unsigned Amt; - if (ArgVT == MVT::i32) - Amt = 4; - else { - assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && - "Other types should have been promoted for varargs!"); - Amt = 8; - } - Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val, - DAG.getConstant(Amt, Val.getValueType())); - Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, - Val, VAListP, DAG.getSrcValue(VAListV)); - return std::make_pair(Result, Chain); -} - -//===----------------------------------------------------------------------===// -// Fast Calling Convention implementation -//===----------------------------------------------------------------------===// -// -// The X86 'fast' calling convention passes up to two integer arguments in -// registers (an appropriate portion of EAX/EDX), passes arguments in C order, -// and requires that the callee pop its arguments off the stack (allowing proper -// tail calls), and has the same return value conventions as C calling convs. -// -// This calling convention always arranges for the callee pop value to be 8n+4 -// bytes, which is needed for tail recursion elimination and stack alignment -// reasons. -// -// Note that this can be enhanced in the future to pass fp vals in registers -// (when we have a global fp allocator) and do other tricks. -// - -/// AddLiveIn - This helper function adds the specified physical register to the -/// MachineFunction as a live in value. It also creates a corresponding virtual -/// register for it. -static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg, - TargetRegisterClass *RC) { - assert(RC->contains(PReg) && "Not the correct regclass!"); - unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC); - MF.addLiveIn(PReg, VReg); - return VReg; -} - - -std::vector -X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) { - std::vector ArgValues; - - MachineFunction &MF = DAG.getMachineFunction(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - - // Add DAG nodes to load the arguments... On entry to a function the stack - // frame looks like this: - // - // [ESP] -- return address - // [ESP + 4] -- first nonreg argument (leftmost lexically) - // [ESP + 8] -- second nonreg argument, if first argument is 4 bytes in size - // ... - unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot - - // Keep track of the number of integer regs passed so far. This can be either - // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both - // used). - unsigned NumIntRegs = 0; - - for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { - MVT::ValueType ObjectVT = getValueType(I->getType()); - unsigned ArgIncrement = 4; - unsigned ObjSize = 0; - SDOperand ArgValue; - - switch (ObjectVT) { - default: assert(0 && "Unhandled argument type!"); - case MVT::i1: - case MVT::i8: - if (NumIntRegs < 2) { - if (!I->use_empty()) { - unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DL : X86::AL, - X86::R8RegisterClass); - ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i8); - DAG.setRoot(ArgValue.getValue(1)); - } - ++NumIntRegs; - break; - } - - ObjSize = 1; - break; - case MVT::i16: - if (NumIntRegs < 2) { - if (!I->use_empty()) { - unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DX : X86::AX, - X86::R16RegisterClass); - ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i16); - DAG.setRoot(ArgValue.getValue(1)); - } - ++NumIntRegs; - break; - } - ObjSize = 2; - break; - case MVT::i32: - if (NumIntRegs < 2) { - if (!I->use_empty()) { - unsigned VReg = AddLiveIn(MF,NumIntRegs ? X86::EDX : X86::EAX, - X86::R32RegisterClass); - ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32); - DAG.setRoot(ArgValue.getValue(1)); - } - ++NumIntRegs; - break; - } - ObjSize = 4; - break; - case MVT::i64: - if (NumIntRegs == 0) { - if (!I->use_empty()) { - unsigned BotReg = AddLiveIn(MF, X86::EAX, X86::R32RegisterClass); - unsigned TopReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass); - - SDOperand Low = DAG.getCopyFromReg(DAG.getRoot(), BotReg, MVT::i32); - SDOperand Hi = DAG.getCopyFromReg(Low.getValue(1), TopReg, MVT::i32); - DAG.setRoot(Hi.getValue(1)); - - ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Low, Hi); - } - NumIntRegs = 2; - break; - } else if (NumIntRegs == 1) { - if (!I->use_empty()) { - unsigned BotReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass); - SDOperand Low = DAG.getCopyFromReg(DAG.getRoot(), BotReg, MVT::i32); - DAG.setRoot(Low.getValue(1)); - - // Load the high part from memory. - // Create the frame index object for this incoming parameter... - int FI = MFI->CreateFixedObject(4, ArgOffset); - SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); - SDOperand Hi = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN, - DAG.getSrcValue(NULL)); - ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Low, Hi); - } - ArgOffset += 4; - NumIntRegs = 2; - break; - } - ObjSize = ArgIncrement = 8; - break; - case MVT::f32: ObjSize = 4; break; - case MVT::f64: ObjSize = ArgIncrement = 8; break; - } - - // Don't codegen dead arguments. FIXME: remove this check when we can nuke - // dead loads. - if (ObjSize && !I->use_empty()) { - // Create the frame index object for this incoming parameter... - int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); - - // Create the SelectionDAG nodes corresponding to a load from this - // parameter. - SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); - - ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN, - DAG.getSrcValue(NULL)); - } else if (ArgValue.Val == 0) { - if (MVT::isInteger(ObjectVT)) - ArgValue = DAG.getConstant(0, ObjectVT); - else - ArgValue = DAG.getConstantFP(0, ObjectVT); - } - ArgValues.push_back(ArgValue); - - if (ObjSize) - ArgOffset += ArgIncrement; // Move on to the next argument. - } - - // Make sure the instruction takes 8n+4 bytes to make sure the start of the - // arguments and the arguments after the retaddr has been pushed are aligned. - if ((ArgOffset & 7) == 0) - ArgOffset += 4; - - VarArgsFrameIndex = 0xAAAAAAA; // fastcc functions can't have varargs. - ReturnAddrIndex = 0; // No return address slot generated yet. - BytesToPopOnReturn = ArgOffset; // Callee pops all stack arguments. - BytesCallerReserves = 0; - - // Finally, inform the code generator which regs we return values in. - switch (getValueType(F.getReturnType())) { - default: assert(0 && "Unknown type!"); - case MVT::isVoid: break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - MF.addLiveOut(X86::EAX); - break; - case MVT::i64: - MF.addLiveOut(X86::EAX); - MF.addLiveOut(X86::EDX); - break; - case MVT::f32: - case MVT::f64: - MF.addLiveOut(X86::ST0); - break; - } - return ArgValues; -} - -std::pair -X86TargetLowering::LowerFastCCCallTo(SDOperand Chain, const Type *RetTy, - bool isTailCall, SDOperand Callee, - ArgListTy &Args, SelectionDAG &DAG) { - // Count how many bytes are to be pushed on the stack. - unsigned NumBytes = 0; - - // Keep track of the number of integer regs passed so far. This can be either - // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both - // used). - unsigned NumIntRegs = 0; - - for (unsigned i = 0, e = Args.size(); i != e; ++i) - switch (getValueType(Args[i].second)) { - default: assert(0 && "Unknown value type!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - if (NumIntRegs < 2) { - ++NumIntRegs; - break; - } - // fall through - case MVT::f32: - NumBytes += 4; - break; - case MVT::i64: - if (NumIntRegs == 0) { - NumIntRegs = 2; - break; - } else if (NumIntRegs == 1) { - NumIntRegs = 2; - NumBytes += 4; - break; - } - - // fall through - case MVT::f64: - NumBytes += 8; - break; - } - - // Make sure the instruction takes 8n+4 bytes to make sure the start of the - // arguments and the arguments after the retaddr has been pushed are aligned. - if ((NumBytes & 7) == 0) - NumBytes += 4; - - Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, - DAG.getConstant(NumBytes, getPointerTy())); - - // Arguments go on the stack in reverse order, as specified by the ABI. - unsigned ArgOffset = 0; - SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(), - X86::ESP, MVT::i32); - NumIntRegs = 0; - std::vector Stores; - std::vector RegValuesToPass; - for (unsigned i = 0, e = Args.size(); i != e; ++i) { - switch (getValueType(Args[i].second)) { - default: assert(0 && "Unexpected ValueType for argument!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - if (NumIntRegs < 2) { - RegValuesToPass.push_back(Args[i].first); - ++NumIntRegs; - break; - } - // Fall through - case MVT::f32: { - SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); - ArgOffset += 4; - break; - } - case MVT::i64: - if (NumIntRegs < 2) { // Can pass part of it in regs? - SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, - Args[i].first, DAG.getConstant(1, MVT::i32)); - SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, - Args[i].first, DAG.getConstant(0, MVT::i32)); - RegValuesToPass.push_back(Lo); - ++NumIntRegs; - if (NumIntRegs < 2) { // Pass both parts in regs? - RegValuesToPass.push_back(Hi); - ++NumIntRegs; - } else { - // Pass the high part in memory. - SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Hi, PtrOff, DAG.getSrcValue(NULL))); - ArgOffset += 4; - } - break; - } - // Fall through - case MVT::f64: - SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); - Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); - ArgOffset += 8; - break; - } - } - if (!Stores.empty()) - Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores); - - // Make sure the instruction takes 8n+4 bytes to make sure the start of the - // arguments and the arguments after the retaddr has been pushed are aligned. - if ((ArgOffset & 7) == 0) - ArgOffset += 4; - - std::vector RetVals; - MVT::ValueType RetTyVT = getValueType(RetTy); - - RetVals.push_back(MVT::Other); - - // The result values produced have to be legal. Promote the result. - switch (RetTyVT) { - case MVT::isVoid: break; - default: - RetVals.push_back(RetTyVT); - break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - RetVals.push_back(MVT::i32); - break; - case MVT::f32: - if (X86ScalarSSE) - RetVals.push_back(MVT::f32); - else - RetVals.push_back(MVT::f64); - break; - case MVT::i64: - RetVals.push_back(MVT::i32); - RetVals.push_back(MVT::i32); - break; - } - - std::vector Ops; - Ops.push_back(Chain); - Ops.push_back(Callee); - Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy())); - // Callee pops all arg values on the stack. - Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy())); - - // Pass register arguments as needed. - Ops.insert(Ops.end(), RegValuesToPass.begin(), RegValuesToPass.end()); - - SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, - RetVals, Ops); - Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall); - - SDOperand ResultVal; - switch (RetTyVT) { - case MVT::isVoid: break; - default: - ResultVal = TheCall.getValue(1); - break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1)); - break; - case MVT::f32: - // FIXME: we would really like to remember that this FP_ROUND operation is - // okay to eliminate if we allow excess FP precision. - ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1)); - break; - case MVT::i64: - ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1), - TheCall.getValue(2)); - break; - } - - return std::make_pair(ResultVal, Chain); -} - -SDOperand X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) { - if (ReturnAddrIndex == 0) { - // Set up a frame object for the return address. - MachineFunction &MF = DAG.getMachineFunction(); - ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(4, -4); - } - - return DAG.getFrameIndex(ReturnAddrIndex, MVT::i32); -} - - - -std::pair X86TargetLowering:: -LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, - SelectionDAG &DAG) { - SDOperand Result; - if (Depth) // Depths > 0 not supported yet! - Result = DAG.getConstant(0, getPointerTy()); - else { - SDOperand RetAddrFI = getReturnAddressFrameIndex(DAG); - if (!isFrameAddress) - // Just load the return address - Result = DAG.getLoad(MVT::i32, DAG.getEntryNode(), RetAddrFI, - DAG.getSrcValue(NULL)); - else - Result = DAG.getNode(ISD::SUB, MVT::i32, RetAddrFI, - DAG.getConstant(4, MVT::i32)); - } - return std::make_pair(Result, Chain); -} - -//===----------------------------------------------------------------------===// -// X86 Custom Lowering Hooks -//===----------------------------------------------------------------------===// - -/// LowerOperation - Provide custom lowering hooks for some operations. -/// -SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { - switch (Op.getOpcode()) { - default: assert(0 && "Should not custom lower this!"); - case ISD::SINT_TO_FP: { - assert(Op.getValueType() == MVT::f64 && - Op.getOperand(0).getValueType() == MVT::i64 && - "Unknown SINT_TO_FP to lower!"); - // We lower sint64->FP into a store to a temporary stack slot, followed by a - // FILD64m node. - MachineFunction &MF = DAG.getMachineFunction(); - int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8); - SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); - SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), - Op.getOperand(0), StackSlot, DAG.getSrcValue(NULL)); - std::vector RTs; - RTs.push_back(MVT::f64); - RTs.push_back(MVT::Other); - std::vector Ops; - Ops.push_back(Store); - Ops.push_back(StackSlot); - return DAG.getNode(X86ISD::FILD64m, RTs, Ops); - } - case ISD::FP_TO_SINT: { - assert(Op.getValueType() <= MVT::i64 && Op.getValueType() >= MVT::i16 && - Op.getOperand(0).getValueType() == MVT::f64 && - "Unknown FP_TO_SINT to lower!"); - // We lower FP->sint64 into FISTP64, followed by a load, all to a temporary - // stack slot. - MachineFunction &MF = DAG.getMachineFunction(); - unsigned MemSize = MVT::getSizeInBits(Op.getValueType())/8; - int SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize); - SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); - - unsigned Opc; - switch (Op.getValueType()) { - default: assert(0 && "Invalid FP_TO_SINT to lower!"); - case MVT::i16: Opc = X86ISD::FP_TO_INT16_IN_MEM; break; - case MVT::i32: Opc = X86ISD::FP_TO_INT32_IN_MEM; break; - case MVT::i64: Opc = X86ISD::FP_TO_INT64_IN_MEM; break; - } - - // Build the FP_TO_INT*_IN_MEM - std::vector Ops; - Ops.push_back(DAG.getEntryNode()); - Ops.push_back(Op.getOperand(0)); - Ops.push_back(StackSlot); - SDOperand FIST = DAG.getNode(Opc, MVT::Other, Ops); - - // Load the result. - return DAG.getLoad(Op.getValueType(), FIST, StackSlot, - DAG.getSrcValue(NULL)); - } - } -} - - //===----------------------------------------------------------------------===// // Pattern Matcher Implementation //===----------------------------------------------------------------------===// @@ -3035,60 +2036,6 @@ return Result; } } - - if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { - // FIXME: These special cases should be handled by the lowering impl! - unsigned RHS = CN->getValue(); - bool isNeg = false; - if ((int)RHS < 0) { - isNeg = true; - RHS = -RHS; - } - if (RHS && (RHS & (RHS-1)) == 0) { // Signed division by power of 2? - unsigned Log = Log2_32(RHS); - unsigned SAROpc, SHROpc, ADDOpc, NEGOpc; - switch (N.getValueType()) { - default: assert("Unknown type to signed divide!"); - case MVT::i8: - SAROpc = X86::SAR8ri; - SHROpc = X86::SHR8ri; - ADDOpc = X86::ADD8rr; - NEGOpc = X86::NEG8r; - break; - case MVT::i16: - SAROpc = X86::SAR16ri; - SHROpc = X86::SHR16ri; - ADDOpc = X86::ADD16rr; - NEGOpc = X86::NEG16r; - break; - case MVT::i32: - SAROpc = X86::SAR32ri; - SHROpc = X86::SHR32ri; - ADDOpc = X86::ADD32rr; - NEGOpc = X86::NEG32r; - break; - } - unsigned RegSize = MVT::getSizeInBits(N.getValueType()); - Tmp1 = SelectExpr(N.getOperand(0)); - unsigned TmpReg; - if (Log != 1) { - TmpReg = MakeReg(N.getValueType()); - BuildMI(BB, SAROpc, 2, TmpReg).addReg(Tmp1).addImm(Log-1); - } else { - TmpReg = Tmp1; - } - unsigned TmpReg2 = MakeReg(N.getValueType()); - BuildMI(BB, SHROpc, 2, TmpReg2).addReg(TmpReg).addImm(RegSize-Log); - unsigned TmpReg3 = MakeReg(N.getValueType()); - BuildMI(BB, ADDOpc, 2, TmpReg3).addReg(Tmp1).addReg(TmpReg2); - - unsigned TmpReg4 = isNeg ? MakeReg(N.getValueType()) : Result; - BuildMI(BB, SAROpc, 2, TmpReg4).addReg(TmpReg3).addImm(Log); - if (isNeg) - BuildMI(BB, NEGOpc, 1, Result).addReg(TmpReg4); - return Result; - } - } } if (getRegPressure(N.getOperand(0)) > getRegPressure(N.getOperand(1))) { @@ -4689,10 +3636,10 @@ } -/// createX86PatternInstructionSelector - This pass converts an LLVM function +/// createX86ISelPattern - This pass converts an LLVM function /// into a machine code representation using pattern matching and a machine /// description file. /// -FunctionPass *llvm::createX86PatternInstructionSelector(TargetMachine &TM) { +FunctionPass *llvm::createX86ISelPattern(TargetMachine &TM) { return new ISel(TM); } Index: llvm/lib/Target/X86/X86TargetMachine.cpp diff -u llvm/lib/Target/X86/X86TargetMachine.cpp:1.86 llvm/lib/Target/X86/X86TargetMachine.cpp:1.86.2.1 --- llvm/lib/Target/X86/X86TargetMachine.cpp:1.86 Thu Sep 1 16:38:21 2005 +++ llvm/lib/Target/X86/X86TargetMachine.cpp Wed Nov 16 12:32:45 2005 @@ -106,7 +106,8 @@ // addPassesToEmitFile - We currently use all of the same passes as the JIT // does to emit statically compiled machine code. bool X86TargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType) { + CodeGenFileType FileType, + bool Fast) { if (FileType != TargetMachine::AssemblyFile && FileType != TargetMachine::ObjectFile) return true; @@ -123,7 +124,7 @@ PM.add(createUnreachableBlockEliminationPass()); // Install an instruction selector. - PM.add(createX86PatternInstructionSelector(*this)); + PM.add(createX86ISelPattern(*this)); // Run optional SSA-based machine code optimizations next... if (!NoSSAPeephole) @@ -191,7 +192,7 @@ PM.add(createUnreachableBlockEliminationPass()); // Install an instruction selector. - PM.add(createX86PatternInstructionSelector(TM)); + PM.add(createX86ISelPattern(TM)); // Run optional SSA-based machine code optimizations next... if (!NoSSAPeephole) Index: llvm/lib/Target/X86/X86TargetMachine.h diff -u llvm/lib/Target/X86/X86TargetMachine.h:1.30 llvm/lib/Target/X86/X86TargetMachine.h:1.30.2.1 --- llvm/lib/Target/X86/X86TargetMachine.h:1.30 Thu Sep 1 16:38:21 2005 +++ llvm/lib/Target/X86/X86TargetMachine.h Wed Nov 16 12:32:45 2005 @@ -41,17 +41,11 @@ return &InstrInfo.getRegisterInfo(); } - /// addPassesToEmitMachineCode - Add passes to the specified pass manager to - /// get machine code emitted. This uses a MachineCodeEmitter object to handle - /// actually outputting the machine code and resolving things like the address - /// of functions. This method should returns true if machine code emission is - /// not supported. - /// virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM, MachineCodeEmitter &MCE); virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out, - CodeGenFileType FileType); + CodeGenFileType FileType, bool Fast); static unsigned getModuleMatchQuality(const Module &M); static unsigned getJITMatchQuality(); From bocchino at cs.uiuc.edu Wed Nov 16 12:33:12 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:12 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/projects/Stacker/tools/stkrc/Makefile Message-ID: <200511161833.MAA21333@zion.cs.uiuc.edu> Changes in directory llvm/projects/Stacker/tools/stkrc: Makefile updated: 1.7 -> 1.7.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+2 -2) Makefile | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/projects/Stacker/tools/stkrc/Makefile diff -u llvm/projects/Stacker/tools/stkrc/Makefile:1.7 llvm/projects/Stacker/tools/stkrc/Makefile:1.7.2.1 --- llvm/projects/Stacker/tools/stkrc/Makefile:1.7 Wed May 18 19:54:10 2005 +++ llvm/projects/Stacker/tools/stkrc/Makefile Wed Nov 16 12:33:00 2005 @@ -9,8 +9,8 @@ # Give the name of a library. This will build a dynamic version. # TOOLNAME = stkrc -LLVMLIBS = LLVMAsmParser LLVMBCWriter LLVMTransforms LLVMipo.a LLVMipa.a \ - LLVMScalarOpts LLVMAnalysis.a LLVMTarget.a LLVMTransformUtils \ +LLVMLIBS = LLVMAsmParser LLVMBCWriter LLVMipo.a \ + LLVMScalarOpts.a LLVMTransforms.a LLVMTransformUtils.a LLVMipa.a LLVMAnalysis.a LLVMTarget.a \ LLVMCore LLVMSupport.a LLVMbzip2 LLVMSystem.a CONFIG_FILES = st EXTRA_DIST = st From bocchino at cs.uiuc.edu Wed Nov 16 12:33:12 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:12 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Transforms/Instrumentation/Makefile ProfilingUtils.cpp TraceBasicBlocks.cpp TraceValues.cpp Message-ID: <200511161833.MAA21252@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Instrumentation: Makefile updated: 1.6 -> 1.6.6.1 ProfilingUtils.cpp updated: 1.6 -> 1.6.4.1 TraceBasicBlocks.cpp updated: 1.12 -> 1.12.4.1 TraceValues.cpp updated: 1.74 -> 1.74.4.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+10 -8) Makefile | 2 +- ProfilingUtils.cpp | 3 ++- TraceBasicBlocks.cpp | 2 +- TraceValues.cpp | 11 ++++++----- 4 files changed, 10 insertions(+), 8 deletions(-) Index: llvm/lib/Transforms/Instrumentation/Makefile diff -u llvm/lib/Transforms/Instrumentation/Makefile:1.6 llvm/lib/Transforms/Instrumentation/Makefile:1.6.6.1 --- llvm/lib/Transforms/Instrumentation/Makefile:1.6 Wed Oct 27 18:18:45 2004 +++ llvm/lib/Transforms/Instrumentation/Makefile Wed Nov 16 12:32:50 2005 @@ -6,9 +6,9 @@ # the University of Illinois Open Source License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## + LEVEL = ../../.. LIBRARYNAME = LLVMInstrumentation -PARALLEL_DIRS = ProfilePaths BUILD_ARCHIVE = 1 include $(LEVEL)/Makefile.common Index: llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp diff -u llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp:1.6 llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp:1.6.4.1 --- llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp:1.6 Thu Apr 21 18:40:46 2005 +++ llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp Wed Nov 16 12:32:50 2005 @@ -26,7 +26,8 @@ const PointerType *UIntPtr = PointerType::get(Type::UIntTy); Module &M = *MainFn->getParent(); Function *InitFn = M.getOrInsertFunction(FnName, Type::IntTy, Type::IntTy, - ArgVTy, UIntPtr, Type::UIntTy, 0); + ArgVTy, UIntPtr, Type::UIntTy, + (Type *)0); // This could force argc and argv into programs that wouldn't otherwise have // them, but instead we just pass null values in. Index: llvm/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp diff -u llvm/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp:1.12 llvm/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp:1.12.4.1 --- llvm/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp:1.12 Sat Apr 23 16:38:35 2005 +++ llvm/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp Wed Nov 16 12:32:50 2005 @@ -46,7 +46,7 @@ << "\", \"" << FnName << "\", " << BBNumber << ")\n"); Module &M = *BB->getParent ()->getParent (); Function *InstrFn = M.getOrInsertFunction (FnName, Type::VoidTy, - Type::UIntTy, 0); + Type::UIntTy, (Type *)0); std::vector Args (1); Args[0] = ConstantUInt::get (Type::UIntTy, BBNumber); Index: llvm/lib/Transforms/Instrumentation/TraceValues.cpp diff -u llvm/lib/Transforms/Instrumentation/TraceValues.cpp:1.74 llvm/lib/Transforms/Instrumentation/TraceValues.cpp:1.74.4.1 --- llvm/lib/Transforms/Instrumentation/TraceValues.cpp:1.74 Sat Apr 23 16:38:35 2005 +++ llvm/lib/Transforms/Instrumentation/TraceValues.cpp Wed Nov 16 12:32:50 2005 @@ -130,17 +130,18 @@ // uint (sbyte*) HashPtrFunc = M.getOrInsertFunction("HashPointerToSeqNum", Type::UIntTy, SBP, - 0); + (Type *)0); // void (sbyte*) ReleasePtrFunc = M.getOrInsertFunction("ReleasePointerSeqNum", - Type::VoidTy, SBP, 0); + Type::VoidTy, SBP, (Type *)0); RecordPtrFunc = M.getOrInsertFunction("RecordPointer", - Type::VoidTy, SBP, 0); + Type::VoidTy, SBP, (Type *)0); - PushOnEntryFunc = M.getOrInsertFunction("PushPointerSet", Type::VoidTy, 0); + PushOnEntryFunc = M.getOrInsertFunction("PushPointerSet", Type::VoidTy, + (Type *)0); ReleaseOnReturnFunc = M.getOrInsertFunction("ReleasePointersPopSet", - Type::VoidTy, 0); + Type::VoidTy, (Type *)0); } From bocchino at cs.uiuc.edu Wed Nov 16 12:33:12 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:12 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Transforms/Utils/Local.cpp Makefile Message-ID: <200511161833.MAA21292@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: Local.cpp updated: 1.44.2.1 -> 1.44.2.2 Makefile updated: 1.4 -> 1.4.6.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+2 -142) Local.cpp | 143 -------------------------------------------------------------- Makefile | 1 2 files changed, 2 insertions(+), 142 deletions(-) Index: llvm/lib/Transforms/Utils/Local.cpp diff -u llvm/lib/Transforms/Utils/Local.cpp:1.44.2.1 llvm/lib/Transforms/Utils/Local.cpp:1.44.2.2 --- llvm/lib/Transforms/Utils/Local.cpp:1.44.2.1 Tue Oct 18 14:21:57 2005 +++ llvm/lib/Transforms/Utils/Local.cpp Wed Nov 16 12:32:55 2005 @@ -17,6 +17,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" +#include "llvm/Analysis/ConstantFolding.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/MathExtras.h" #include @@ -235,148 +236,6 @@ return false; } -/// canConstantFoldCallTo - Return true if its even possible to fold a call to -/// the specified function. -bool llvm::canConstantFoldCallTo(Function *F) { - const std::string &Name = F->getName(); - - switch (F->getIntrinsicID()) { - case Intrinsic::isunordered: - case Intrinsic::sqrt: - return true; - default: break; - } - - switch (Name[0]) - { - case 'a': - return Name == "acos" || Name == "asin" || Name == "atan" || - Name == "atan2"; - case 'c': - return Name == "ceil" || Name == "cos" || Name == "cosf" || - Name == "cosh"; - case 'e': - return Name == "exp"; - case 'f': - return Name == "fabs" || Name == "fmod" || Name == "floor"; - case 'l': - return Name == "log" || Name == "log10"; - case 'p': - return Name == "pow"; - case 's': - return Name == "sin" || Name == "sinh" || Name == "sqrt"; - case 't': - return Name == "tan" || Name == "tanh"; - default: - return false; - } -} - -static Constant *ConstantFoldFP(double (*NativeFP)(double), double V, - const Type *Ty) { - errno = 0; - V = NativeFP(V); - if (errno == 0) - return ConstantFP::get(Ty, V); - return 0; -} - -/// ConstantFoldCall - Attempt to constant fold a call to the specified function -/// with the specified arguments, returning null if unsuccessful. -Constant *llvm::ConstantFoldCall(Function *F, - const std::vector &Operands) { - const std::string &Name = F->getName(); - const Type *Ty = F->getReturnType(); - - if (Operands.size() == 1) { - if (ConstantFP *Op = dyn_cast(Operands[0])) { - double V = Op->getValue(); - switch (Name[0]) - { - case 'a': - if (Name == "acos") - return ConstantFoldFP(acos, V, Ty); - else if (Name == "asin") - return ConstantFoldFP(asin, V, Ty); - else if (Name == "atan") - return ConstantFP::get(Ty, atan(V)); - break; - case 'c': - if (Name == "ceil") - return ConstantFoldFP(ceil, V, Ty); - else if (Name == "cos") - return ConstantFP::get(Ty, cos(V)); - else if (Name == "cosh") - return ConstantFP::get(Ty, cosh(V)); - break; - case 'e': - if (Name == "exp") - return ConstantFP::get(Ty, exp(V)); - break; - case 'f': - if (Name == "fabs") - return ConstantFP::get(Ty, fabs(V)); - else if (Name == "floor") - return ConstantFoldFP(floor, V, Ty); - break; - case 'l': - if (Name == "log" && V > 0) - return ConstantFP::get(Ty, log(V)); - else if (Name == "log10" && V > 0) - return ConstantFoldFP(log10, V, Ty); - else if (Name == "llvm.sqrt") { - if (V >= -0.0) - return ConstantFP::get(Ty, sqrt(V)); - else // Undefined - return ConstantFP::get(Ty, 0.0); - } - break; - case 's': - if (Name == "sin") - return ConstantFP::get(Ty, sin(V)); - else if (Name == "sinh") - return ConstantFP::get(Ty, sinh(V)); - else if (Name == "sqrt" && V >= 0) - return ConstantFP::get(Ty, sqrt(V)); - break; - case 't': - if (Name == "tan") - return ConstantFP::get(Ty, tan(V)); - else if (Name == "tanh") - return ConstantFP::get(Ty, tanh(V)); - break; - default: - break; - } - } - } else if (Operands.size() == 2) { - if (ConstantFP *Op1 = dyn_cast(Operands[0])) { - double Op1V = Op1->getValue(); - if (ConstantFP *Op2 = dyn_cast(Operands[1])) { - double Op2V = Op2->getValue(); - - if (Name == "llvm.isunordered") - return ConstantBool::get(IsNAN(Op1V) || IsNAN(Op2V)); - else - if (Name == "pow") { - errno = 0; - double V = pow(Op1V, Op2V); - if (errno == 0) - return ConstantFP::get(Ty, V); - } else if (Name == "fmod") { - errno = 0; - double V = fmod(Op1V, Op2V); - if (errno == 0) - return ConstantFP::get(Ty, V); - } else if (Name == "atan2") - return ConstantFP::get(Ty, atan2(Op1V,Op2V)); - } - } - } - return 0; -} - - /// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a /// getelementptr constantexpr, return the constant value being addressed by the /// constant expression, or null if something is funny and we can't decide. Index: llvm/lib/Transforms/Utils/Makefile diff -u llvm/lib/Transforms/Utils/Makefile:1.4 llvm/lib/Transforms/Utils/Makefile:1.4.6.1 --- llvm/lib/Transforms/Utils/Makefile:1.4 Wed Oct 27 18:18:45 2004 +++ llvm/lib/Transforms/Utils/Makefile Wed Nov 16 12:32:55 2005 @@ -6,6 +6,7 @@ # the University of Illinois Open Source License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## + LEVEL = ../../.. LIBRARYNAME = LLVMTransformUtils BUILD_ARCHIVE = 1 From bocchino at cs.uiuc.edu Wed Nov 16 12:33:18 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:18 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/projects/sample/autoconf/aclocal.m4 install-sh ltmain.sh mkinstalldirs Message-ID: <200511161833.MAA21370@zion.cs.uiuc.edu> Changes in directory llvm/projects/sample/autoconf: aclocal.m4 (r1.1) removed install-sh (r1.1) removed ltmain.sh (r1.1) removed mkinstalldirs (r1.1) removed --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+0 -0) 0 files changed From bocchino at cs.uiuc.edu Wed Nov 16 12:33:12 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:12 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Transforms/Vector/Alloca2Realloc.cpp AltiVec.cpp LowerVectors.cpp RaiseVectors.cpp SSE.cpp Message-ID: <200511161833.MAA21305@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Vector: Alloca2Realloc.cpp updated: 1.1.2.1 -> 1.1.2.2 AltiVec.cpp updated: 1.1.2.2 -> 1.1.2.3 LowerVectors.cpp updated: 1.1.2.2 -> 1.1.2.3 RaiseVectors.cpp updated: 1.1.2.2 -> 1.1.2.3 SSE.cpp updated: 1.1.2.2 -> 1.1.2.3 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+503 -484) Alloca2Realloc.cpp | 3 AltiVec.cpp | 3 LowerVectors.cpp | 5 RaiseVectors.cpp | 973 ++++++++++++++++++++++++++--------------------------- SSE.cpp | 3 5 files changed, 503 insertions(+), 484 deletions(-) Index: llvm/lib/Transforms/Vector/Alloca2Realloc.cpp diff -u llvm/lib/Transforms/Vector/Alloca2Realloc.cpp:1.1.2.1 llvm/lib/Transforms/Vector/Alloca2Realloc.cpp:1.1.2.2 --- llvm/lib/Transforms/Vector/Alloca2Realloc.cpp:1.1.2.1 Tue Oct 18 14:37:03 2005 +++ llvm/lib/Transforms/Vector/Alloca2Realloc.cpp Wed Nov 16 12:32:56 2005 @@ -28,6 +28,7 @@ #include "llvm/Pass.h" #include "llvm/DerivedTypes.h" #include "llvm/Support/Debug.h" +#include "llvm/Transforms/Scalar.h" using namespace llvm; @@ -210,3 +211,5 @@ } } + +FunctionPass *llvm::createAlloca2ReallocPass() { return new Alloca2Realloc(); } Index: llvm/lib/Transforms/Vector/AltiVec.cpp diff -u llvm/lib/Transforms/Vector/AltiVec.cpp:1.1.2.2 llvm/lib/Transforms/Vector/AltiVec.cpp:1.1.2.3 --- llvm/lib/Transforms/Vector/AltiVec.cpp:1.1.2.2 Tue Nov 15 14:15:33 2005 +++ llvm/lib/Transforms/Vector/AltiVec.cpp Wed Nov 16 12:32:56 2005 @@ -26,6 +26,7 @@ #include "llvm/ADT/hash_set" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/InstVisitor.h" +#include "llvm/Transforms/Scalar.h" #include "VectorLLVM/Utils.h" using namespace llvm; @@ -521,3 +522,5 @@ } } + +FunctionPass *llvm::createAltiVecPass() { return new AltiVec(); } Index: llvm/lib/Transforms/Vector/LowerVectors.cpp diff -u llvm/lib/Transforms/Vector/LowerVectors.cpp:1.1.2.2 llvm/lib/Transforms/Vector/LowerVectors.cpp:1.1.2.3 --- llvm/lib/Transforms/Vector/LowerVectors.cpp:1.1.2.2 Tue Nov 15 14:15:33 2005 +++ llvm/lib/Transforms/Vector/LowerVectors.cpp Wed Nov 16 12:32:56 2005 @@ -78,7 +78,7 @@ RegisterOpt X("lowervectors", "Lower vector operations to iterated scalar operations"); - + class VMemoryInstLowering { protected: BasicBlock *constructLoop(VMemoryInst*,BasicBlock*,std::vector,Value*); @@ -1103,3 +1103,6 @@ } } + +FunctionPass *llvm::createLowerVectorsPass() { return new LowerVectors(); } + Index: llvm/lib/Transforms/Vector/RaiseVectors.cpp diff -u llvm/lib/Transforms/Vector/RaiseVectors.cpp:1.1.2.2 llvm/lib/Transforms/Vector/RaiseVectors.cpp:1.1.2.3 --- llvm/lib/Transforms/Vector/RaiseVectors.cpp:1.1.2.2 Tue Nov 15 14:15:33 2005 +++ llvm/lib/Transforms/Vector/RaiseVectors.cpp Wed Nov 16 12:32:56 2005 @@ -19,6 +19,7 @@ #include "llvm/Instructions.h" #include "llvm/Pass.h" #include "llvm/Type.h" +#include "llvm/Transforms/Scalar.h" #include "llvm/Support/Debug.h" #include "llvm/ADT/hash_map" #include "llvm/ADT/hash_set" @@ -77,521 +78,527 @@ }; + RegisterOpt X("raisevectors", "Raise Vector-C significant functions to Vector-LLVM"); +} - //===----------------------------------------------------------------------===// - // RaiseVectors implementation - //===----------------------------------------------------------------------===// +FunctionPass *llvm::createRaiseVectorsPass() { return new RaiseVectors(); } - /// llvm-gcc is very permissive about function declarations -- - /// undeclared functions are treated as int(...). Here we require - /// and check that the user has properly declared all Vector-C - /// significant functions. - /// - bool RaiseVectors::doInitialization(Module &M) { - for (Module::iterator I = M.begin(), E = M.end(); - I != E; ++I) { - if (!VectorSignificantFunctions::isProperlyDeclared(I)) { - std::cerr << "Significant function " << I->getName() - << " was not declared or was improperly declared.\n"; - exit(1); - } + +//===----------------------------------------------------------------------===// +// RaiseVectors implementation +//===----------------------------------------------------------------------===// + +/// llvm-gcc is very permissive about function declarations -- +/// undeclared functions are treated as int(...). Here we require +/// and check that the user has properly declared all Vector-C +/// significant functions. +/// +bool RaiseVectors::doInitialization(Module &M) { + for (Module::iterator I = M.begin(), E = M.end(); + I != E; ++I) { + if (!VectorSignificantFunctions::isProperlyDeclared(I)) { + std::cerr << "Significant function " << I->getName() + << " was not declared or was improperly declared.\n"; + exit(1); } - return false; } + return false; +} - /// Main function called by PassManager - /// - bool RaiseVectors::runOnFunction(Function &F) { - DEBUG(std::cerr << "\nrunOnFunction(" << F.getName() << ")\n"); - - raisingMap.clear(); - workList.clear(); - raisedInstructions.clear(); - bool changed = addDefsToWorklist(F); - - if (changed) { - raiseInstructions(); - deleteRaisedInstructions(); - } - - return changed; - - } +/// Main function called by PassManager +/// +bool RaiseVectors::runOnFunction(Function &F) { + DEBUG(std::cerr << "\nrunOnFunction(" << F.getName() << ")\n"); + + raisingMap.clear(); + workList.clear(); + raisedInstructions.clear(); + bool changed = addDefsToWorklist(F); + + if (changed) { + raiseInstructions(); + deleteRaisedInstructions(); + } + + return changed; + +} - /// Add all vector definitions to the work list - /// - bool RaiseVectors::addDefsToWorklist(Function& F) { - bool defFound = false; - for (Function::iterator FI = F.begin(), FE = F.end(); - FI != FE; ++FI) { - for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); - BI != BE; ++BI) { - if (CallInst *CI = dyn_cast(BI)) { - if (Function* F = CI->getCalledFunction()) { - VectorSignificantFunctions::ID id = - VectorSignificantFunctions::getID(F->getName()); - if (id == VectorSignificantFunctions::vload || - id == VectorSignificantFunctions::vgather || - id == VectorSignificantFunctions::vloadi || - id == VectorSignificantFunctions::vimm || - id == VectorSignificantFunctions::fixed_vimm || - id == VectorSignificantFunctions::load || - id == VectorSignificantFunctions::constant) { - workList.push_back(CI); - defFound = true; - } +/// Add all vector definitions to the work list +/// +bool RaiseVectors::addDefsToWorklist(Function& F) { + bool defFound = false; + for (Function::iterator FI = F.begin(), FE = F.end(); + FI != FE; ++FI) { + for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); + BI != BE; ++BI) { + if (CallInst *CI = dyn_cast(BI)) { + if (Function* F = CI->getCalledFunction()) { + VectorSignificantFunctions::ID id = + VectorSignificantFunctions::getID(F->getName()); + if (id == VectorSignificantFunctions::vload || + id == VectorSignificantFunctions::vgather || + id == VectorSignificantFunctions::vloadi || + id == VectorSignificantFunctions::vimm || + id == VectorSignificantFunctions::fixed_vimm || + id == VectorSignificantFunctions::load || + id == VectorSignificantFunctions::constant) { + workList.push_back(CI); + defFound = true; } } } } - return defFound; - } + return defFound; + +} - /// Raise all instructions on the worklist. - /// - void RaiseVectors::raiseInstructions() { - // Visit all the instructions to be raised. As uses are - // encountered, they are added to the worklist. - // - while (workList.size() > 0) { - Instruction *I = workList.back(); - workList.pop_back(); - if(raisedInstructions.insert(I).second) { - DEBUG(std::cerr << "Raising " << *I); - visit(*I); - DEBUG(if (raisingMap[I]) {std::cerr << "Raised value is " << *raisingMap[I];}); - } - } - // Check for leftover dummy values indicating the program - // attempted to combine a scalar with a vector - // - for (hash_map::iterator I = raisingMap.begin(), - E = raisingMap.end(); I != E; ++I) { - if (I->second && isa(I->second)) { - std::cerr << "Value was never raised!\n"; - std::cerr << *(I->first) << "\n"; - std::cerr << "This is because you used a scalar value in a vector operation.\n"; - std::cerr << "Use vimm to promote scalars to vectors " - << "before combining them with vectors.\n"; - exit(1); - } +/// Raise all instructions on the worklist. +/// +void RaiseVectors::raiseInstructions() { + // Visit all the instructions to be raised. As uses are + // encountered, they are added to the worklist. + // + while (workList.size() > 0) { + Instruction *I = workList.back(); + workList.pop_back(); + if(raisedInstructions.insert(I).second) { + DEBUG(std::cerr << "Raising " << *I); + visit(*I); + DEBUG(if (raisingMap[I]) {std::cerr << "Raised value is " << *raisingMap[I];}); + } + } + // Check for leftover dummy values indicating the program + // attempted to combine a scalar with a vector + // + for (hash_map::iterator I = raisingMap.begin(), + E = raisingMap.end(); I != E; ++I) { + if (I->second && isa(I->second)) { + std::cerr << "Value was never raised!\n"; + std::cerr << *(I->first) << "\n"; + std::cerr << "This is because you used a scalar value in a vector operation.\n"; + std::cerr << "Use vimm to promote scalars to vectors " + << "before combining them with vectors.\n"; + exit(1); } } +} - /// Delete all instructions that we have raised. - /// - void RaiseVectors::deleteRaisedInstructions() { +/// Delete all instructions that we have raised. +/// +void RaiseVectors::deleteRaisedInstructions() { + + for (hash_set::iterator I = raisedInstructions.begin(), + E = raisedInstructions.end(); I != E; ++I) { + DEBUG(std::cerr << "Dropping all references from " << **I); + (*I)->dropAllReferences(); + } + + for (hash_set::iterator I = raisedInstructions.begin(), + E = raisedInstructions.end(); I != E; ++I) { + (*I)->getParent()->getInstList().erase(*I); + } +} - for (hash_set::iterator I = raisedInstructions.begin(), - E = raisedInstructions.end(); I != E; ++I) { - DEBUG(std::cerr << "Dropping all references from " << **I); - (*I)->dropAllReferences(); +/// Raise a significant function call +/// +void RaiseVectors::visitCallInst(CallInst &CI) { + Function *F = CI.getCalledFunction(); + if (!F) { + std::cerr << "Can't handle indirect function call " << CI; + exit(1); + } + std::string name = F->getName(); + Value *raisedValue; + switch(VectorSignificantFunctions::getID(name)) { + case VectorSignificantFunctions::vload: + case VectorSignificantFunctions::vgather: { + std::vector idx; + for (unsigned i = 2; i < CI.getNumOperands(); ++i) { + CastInst *castInst = + new CastInst(CI.getOperand(i), Type::LongTy, "cast", &CI); + idx.push_back(castInst); } - - for (hash_set::iterator I = raisedInstructions.begin(), - E = raisedInstructions.end(); I != E; ++I) { - (*I)->getParent()->getInstList().erase(*I); + raisedValue = new VGatherInst(CI.getOperand(1), + idx, "vgather", &CI); + addUsesToWorklist(&CI); + break; + } + case VectorSignificantFunctions::load: { + ConstantUInt *UIntVal = dyn_cast(CI.getOperand(2)); + assert(UIntVal && "Vector length must be a constant UInt!"); + const PointerType *PointerTy = + dyn_cast(CI.getOperand(1)->getType()); + assert(PointerTy && "Pointer operand must be pointer type!"); + CastInst *cast = + new CastInst(CI.getOperand(1), + PointerType::get(FixedVectorType::get(PointerTy->getElementType(), + UIntVal->getValue())), + "cast", &CI); + std::vector Idx; + Idx.push_back(CI.getOperand(3)); + GetElementPtrInst *GEP = + new GetElementPtrInst(cast, Idx, "gep", &CI); + raisedValue = new LoadInst(GEP, "load", &CI); + addUsesToWorklist(&CI); + break; + } + case VectorSignificantFunctions::vimm: + case VectorSignificantFunctions::vloadi: { + raisedValue = new VImmInst(CI.getOperand(1), CI.getOperand(2), false, + "vimm", &CI); + const VectorType *VT = VectorType::get(CI.getOperand(1)->getType()); + if (raisedValue->getType() != VT) + raisedValue = new CastInst(raisedValue, VT, "cast", &CI); + addUsesToWorklist(&CI); + break; + } + case VectorSignificantFunctions::constant: { + std::vector elements; + for (unsigned i = 1; i < CI.getNumOperands(); ++i) { + Constant *C = dyn_cast(CI.getOperand(i)); + assert(C && "Operands of constant must be constants!"); + elements.push_back(ConstantExpr::getCast(C, CI.getType())); } + raisedValue = ConstantVector::get(elements); + addUsesToWorklist(&CI); + break; } - - /// Raise a significant function call - /// - void RaiseVectors::visitCallInst(CallInst &CI) { - Function *F = CI.getCalledFunction(); - if (!F) { - std::cerr << "Can't handle indirect function call " << CI; + case VectorSignificantFunctions::fixed_vimm: { + ConstantUInt *UIntVal = dyn_cast(CI.getOperand(2)); + assert(UIntVal && "Vector length must be a constant UInt!"); + raisedValue = new VImmInst(CI.getOperand(1), CI.getOperand(2), + true, "vimm", &CI); + const FixedVectorType *VT = FixedVectorType::get(CI.getType(), UIntVal->getValue()); + if (raisedValue->getType() != VT) + raisedValue = new CastInst(raisedValue, VT, "cast", &CI); + addUsesToWorklist(&CI); + break; + } + case VectorSignificantFunctions::vstore: + case VectorSignificantFunctions::vscatter: { + std::vector idx; + for (unsigned i = 3; i < CI.getNumOperands(); ++i) { + CastInst *castInst = + new CastInst(CI.getOperand(i), Type::LongTy, "cast", &CI); + idx.push_back(castInst); + } + Value *raisedOp = getRaisedValue(CI.getOperand(1), (unsigned) 0); + Value *ptr = CI.getOperand(2); + raisedValue = new VScatterInst(raisedOp, ptr, idx, &CI); + break; + } + case VectorSignificantFunctions::store: { + unsigned length = getVectorLength(&CI); + Value *op1 = getRaisedValue(CI.getOperand(1), length); + const PointerType *PointerTy = + dyn_cast(CI.getOperand(2)->getType()); + assert(PointerTy && "Pointer operand must be pointer type!"); + CastInst *cast = + new CastInst(CI.getOperand(2), + PointerType::get(FixedVectorType::get(PointerTy->getElementType(), + length)), + "cast", &CI); + std::vector Idx; + Idx.push_back(CI.getOperand(3)); + GetElementPtrInst *GEP = + new GetElementPtrInst(cast, Idx, "gep", &CI); + raisedValue = new StoreInst(op1, GEP, &CI); + break; + } + case VectorSignificantFunctions::vselect: { + unsigned numArgs = 3; + unsigned length = getVectorLength(&CI); + assert((CI.getNumOperands() == numArgs+1) && + "Wrong number of arguments to _select!"); + CastInst *cast = dyn_cast(CI.getOperand(1)); + assert(cast && "First operand of vselect must be cast!"); + assert(cast->getOperand(0)->getType() == Type::BoolTy && + "First operand of vselect must be cast of bool to int!"); + Value *raisedArgs[numArgs]; + raisedArgs[0] = getRaisedValue(cast->getOperand(0), length); + for (unsigned i = 1; i < numArgs; ++i) { + Value *arg = CI.getOperand(i+1); + raisedArgs[i] = getRaisedValue(arg, length); + } + raisedValue = + new VSelectInst(raisedArgs[0], raisedArgs[1], raisedArgs[2], "vselect", &CI); + addUsesToWorklist(&CI); + break; + } + case VectorSignificantFunctions::extract: { + Value *raisedOp = getRaisedOperand(&CI, 1); + raisedValue = new ExtractInst(raisedOp, CI.getOperand(2), + CI.getOperand(3), CI.getOperand(4), + "extract", &CI); + addUsesToWorklist(&CI); + break; + } + case VectorSignificantFunctions::combine: { + unsigned length = getVectorLength(&CI); + Value *raisedOp1 = getRaisedValue(CI.getOperand(1), length); + Value *raisedOp2 = getRaisedValue(CI.getOperand(2), length); + raisedValue = new CombineInst(raisedOp1, raisedOp2, + CI.getOperand(3), CI.getOperand(4), + "combine", &CI); + addUsesToWorklist(&CI); + + break; + } + case VectorSignificantFunctions::fixed_combine: { + ConstantUInt *op2 = dyn_cast(CI.getOperand(2)); + ConstantUInt *op4 = dyn_cast(CI.getOperand(4)); + assert((op2 && op4) && "Vector length operands to fixed_combine must be constant uints!"); + unsigned length1 = op2->getValue(); + unsigned length2 = op4->getValue(); + Value *raisedOp1 = getRaisedValue(CI.getOperand(1), length1); + Value *raisedOp2 = getRaisedValue(CI.getOperand(3), length2); + raisedValue = new CombineInst(raisedOp1, raisedOp2, + CI.getOperand(5), CI.getOperand(6), + "combine", &CI); + addUsesToWorklist(&CI); + break; + } + case VectorSignificantFunctions::fixed_permute: { + ConstantUInt *op2 = dyn_cast(CI.getOperand(2)); + ConstantUInt *op4 = dyn_cast(CI.getOperand(4)); + assert((op2 && op4) && "Vector length operands to fixed_combine must be constant uints!"); + unsigned length1 = op2->getValue(); + unsigned length2 = op4->getValue(); + Value *raisedOp1 = getRaisedValue(CI.getOperand(1), length1); + Value *raisedOp2 = getRaisedValue(CI.getOperand(3), length2); + raisedValue = VectorUtils::getCallInst(raisedOp2->getType(), "vllvm_permute_" + + cast(raisedOp2->getType())->getElementType()->getDescription(), + raisedOp1, raisedOp2, "permute", &CI); + addUsesToWorklist(&CI); + break; + } + case VectorSignificantFunctions::extractelement: { + Value *raisedOp = getRaisedOperand(&CI, 1); + raisedValue = + new ExtractElementInst(raisedOp, CI.getOperand(2), + "extractelement", &CI); + CI.replaceAllUsesWith(raisedValue); + break; + } + case VectorSignificantFunctions::combineelement: { + Value *raisedOp1 = getRaisedOperand(&CI, 1); + raisedValue = new CombineElementInst(raisedOp1, CI.getOperand(2), + CI.getOperand(3), "combineelement", &CI); + addUsesToWorklist(&CI); + break; + } + default: + if (name.substr(0, 7) == "vectorc") { + name.erase(0, 7); + name = "vllvm" + name; + } + else if (name.substr(0, 5) == "vllvm") { + name += "_vector"; + } else { + std::cerr << "Can't handle instruction " << CI; exit(1); } - std::string name = F->getName(); - Value *raisedValue; - switch(VectorSignificantFunctions::getID(name)) { - case VectorSignificantFunctions::vload: - case VectorSignificantFunctions::vgather: { - std::vector idx; - for (unsigned i = 2; i < CI.getNumOperands(); ++i) { - CastInst *castInst = - new CastInst(CI.getOperand(i), Type::LongTy, "cast", &CI); - idx.push_back(castInst); - } - raisedValue = new VGatherInst(CI.getOperand(1), - idx, "vgather", &CI); - addUsesToWorklist(&CI); - break; - } - case VectorSignificantFunctions::load: { - ConstantUInt *UIntVal = dyn_cast(CI.getOperand(2)); - assert(UIntVal && "Vector length must be a constant UInt!"); - const PointerType *PointerTy = - dyn_cast(CI.getOperand(1)->getType()); - assert(PointerTy && "Pointer operand must be pointer type!"); - CastInst *cast = - new CastInst(CI.getOperand(1), - PointerType::get(FixedVectorType::get(PointerTy->getElementType(), - UIntVal->getValue())), - "cast", &CI); - std::vector Idx; - Idx.push_back(CI.getOperand(3)); - GetElementPtrInst *GEP = - new GetElementPtrInst(cast, Idx, "gep", &CI); - raisedValue = new LoadInst(GEP, "load", &CI); - addUsesToWorklist(&CI); - break; - } - case VectorSignificantFunctions::vimm: - case VectorSignificantFunctions::vloadi: { - raisedValue = new VImmInst(CI.getOperand(1), CI.getOperand(2), false, - "vimm", &CI); - const VectorType *VT = VectorType::get(CI.getOperand(1)->getType()); - if (raisedValue->getType() != VT) - raisedValue = new CastInst(raisedValue, VT, "cast", &CI); - addUsesToWorklist(&CI); - break; - } - case VectorSignificantFunctions::constant: { - std::vector elements; - for (unsigned i = 1; i < CI.getNumOperands(); ++i) { - Constant *C = dyn_cast(CI.getOperand(i)); - assert(C && "Operands of constant must be constants!"); - elements.push_back(ConstantExpr::getCast(C, CI.getType())); - } - raisedValue = ConstantVector::get(elements); - addUsesToWorklist(&CI); - break; - } - case VectorSignificantFunctions::fixed_vimm: { - ConstantUInt *UIntVal = dyn_cast(CI.getOperand(2)); - assert(UIntVal && "Vector length must be a constant UInt!"); - raisedValue = new VImmInst(CI.getOperand(1), CI.getOperand(2), - true, "vimm", &CI); - const FixedVectorType *VT = FixedVectorType::get(CI.getType(), UIntVal->getValue()); - if (raisedValue->getType() != VT) - raisedValue = new CastInst(raisedValue, VT, "cast", &CI); - addUsesToWorklist(&CI); - break; - } - case VectorSignificantFunctions::vstore: - case VectorSignificantFunctions::vscatter: { - std::vector idx; - for (unsigned i = 3; i < CI.getNumOperands(); ++i) { - CastInst *castInst = - new CastInst(CI.getOperand(i), Type::LongTy, "cast", &CI); - idx.push_back(castInst); - } - Value *raisedOp = getRaisedValue(CI.getOperand(1), (unsigned) 0); - Value *ptr = CI.getOperand(2); - raisedValue = new VScatterInst(raisedOp, ptr, idx, &CI); - break; - } - case VectorSignificantFunctions::store: { - unsigned length = getVectorLength(&CI); - Value *op1 = getRaisedValue(CI.getOperand(1), length); - const PointerType *PointerTy = - dyn_cast(CI.getOperand(2)->getType()); - assert(PointerTy && "Pointer operand must be pointer type!"); - CastInst *cast = - new CastInst(CI.getOperand(2), - PointerType::get(FixedVectorType::get(PointerTy->getElementType(), - length)), - "cast", &CI); - std::vector Idx; - Idx.push_back(CI.getOperand(3)); - GetElementPtrInst *GEP = - new GetElementPtrInst(cast, Idx, "gep", &CI); - raisedValue = new StoreInst(op1, GEP, &CI); - break; - } - case VectorSignificantFunctions::vselect: { - unsigned numArgs = 3; - unsigned length = getVectorLength(&CI); - assert((CI.getNumOperands() == numArgs+1) && - "Wrong number of arguments to _select!"); - CastInst *cast = dyn_cast(CI.getOperand(1)); - assert(cast && "First operand of vselect must be cast!"); - assert(cast->getOperand(0)->getType() == Type::BoolTy && - "First operand of vselect must be cast of bool to int!"); - Value *raisedArgs[numArgs]; - raisedArgs[0] = getRaisedValue(cast->getOperand(0), length); - for (unsigned i = 1; i < numArgs; ++i) { - Value *arg = CI.getOperand(i+1); - raisedArgs[i] = getRaisedValue(arg, length); - } - raisedValue = - new VSelectInst(raisedArgs[0], raisedArgs[1], raisedArgs[2], "vselect", &CI); - addUsesToWorklist(&CI); - break; - } - case VectorSignificantFunctions::extract: { - Value *raisedOp = getRaisedOperand(&CI, 1); - raisedValue = new ExtractInst(raisedOp, CI.getOperand(2), - CI.getOperand(3), CI.getOperand(4), - "extract", &CI); - addUsesToWorklist(&CI); - break; - } - case VectorSignificantFunctions::combine: { - unsigned length = getVectorLength(&CI); - Value *raisedOp1 = getRaisedValue(CI.getOperand(1), length); - Value *raisedOp2 = getRaisedValue(CI.getOperand(2), length); - raisedValue = new CombineInst(raisedOp1, raisedOp2, - CI.getOperand(3), CI.getOperand(4), - "combine", &CI); - addUsesToWorklist(&CI); - - break; - } - case VectorSignificantFunctions::fixed_combine: { - ConstantUInt *op2 = dyn_cast(CI.getOperand(2)); - ConstantUInt *op4 = dyn_cast(CI.getOperand(4)); - assert((op2 && op4) && "Vector length operands to fixed_combine must be constant uints!"); - unsigned length1 = op2->getValue(); - unsigned length2 = op4->getValue(); - Value *raisedOp1 = getRaisedValue(CI.getOperand(1), length1); - Value *raisedOp2 = getRaisedValue(CI.getOperand(3), length2); - raisedValue = new CombineInst(raisedOp1, raisedOp2, - CI.getOperand(5), CI.getOperand(6), - "combine", &CI); - addUsesToWorklist(&CI); - break; - } - case VectorSignificantFunctions::fixed_permute: { - ConstantUInt *op2 = dyn_cast(CI.getOperand(2)); - ConstantUInt *op4 = dyn_cast(CI.getOperand(4)); - assert((op2 && op4) && "Vector length operands to fixed_combine must be constant uints!"); - unsigned length1 = op2->getValue(); - unsigned length2 = op4->getValue(); - Value *raisedOp1 = getRaisedValue(CI.getOperand(1), length1); - Value *raisedOp2 = getRaisedValue(CI.getOperand(3), length2); - raisedValue = VectorUtils::getCallInst(raisedOp2->getType(), "vllvm_permute_" + - cast(raisedOp2->getType())->getElementType()->getDescription(), - raisedOp1, raisedOp2, "permute", &CI); - addUsesToWorklist(&CI); - break; - } - case VectorSignificantFunctions::extractelement: { - Value *raisedOp = getRaisedOperand(&CI, 1); - raisedValue = - new ExtractElementInst(raisedOp, CI.getOperand(2), - "extractelement", &CI); - CI.replaceAllUsesWith(raisedValue); - break; - } - case VectorSignificantFunctions::combineelement: { - Value *raisedOp1 = getRaisedOperand(&CI, 1); - raisedValue = new CombineElementInst(raisedOp1, CI.getOperand(2), - CI.getOperand(3), "combineelement", &CI); - addUsesToWorklist(&CI); - break; - } - default: - if (name.substr(0, 7) == "vectorc") { - name.erase(0, 7); - name = "vllvm" + name; - } - else if (name.substr(0, 5) == "vllvm") { - name += "_vector"; + unsigned length = getVectorLength(&CI); + std::vector formalArgs; + std::vector args; + for (unsigned i = 1; i < CI.getNumOperands(); ++i) { + Value *op = CI.getOperand(i); + if (isa(op)) { + formalArgs.push_back(op->getType()); + args.push_back(op); } else { - std::cerr << "Can't handle instruction " << CI; - exit(1); - } - unsigned length = getVectorLength(&CI); - std::vector formalArgs; - std::vector args; - for (unsigned i = 1; i < CI.getNumOperands(); ++i) { - Value *op = CI.getOperand(i); - if (isa(op)) { - formalArgs.push_back(op->getType()); - args.push_back(op); - } else { - formalArgs.push_back(getRaisedType(CI.getOperand(i)->getType(), length)); - args.push_back(getRaisedOperand(&CI, i)); - } - } - FunctionType *FType = - FunctionType::get(getRaisedType(F->getReturnType(), length), formalArgs, false); - Module *M = CI.getParent()->getParent()->getParent(); - Function *func = M->getOrInsertFunction(name, FType); - raisedValue = new CallInst(func, args, "func", &CI); - addUsesToWorklist(&CI); - break; - } - setRaisedValue(&CI, raisedValue); - } - - /// Raise a binary operator - /// - void RaiseVectors::visitBinaryOperator(BinaryOperator &BO) { - unsigned length = getVectorLength(&BO); - Value *newOp[2]; - for (unsigned i = 0; i < 2; ++i) { - newOp[i] = getRaisedValue(BO.getOperand(i), length); - } - Instruction::BinaryOps raisedOp; - if (SetCondInst *SI = dyn_cast(&BO)) - raisedOp = SI->getVectorOpcode(); - else raisedOp = BO.getOpcode(); - Instruction *raisedValue = - BinaryOperator::create(raisedOp, newOp[0], newOp[1], "binop", &BO); - setRaisedValue(&BO, raisedValue); - addUsesToWorklist(&BO); - } - - /// Raise a cast instruction - /// - void RaiseVectors::visitCastInst(CastInst &CI) { - // Don't raise the cast if it's a cast of a bool to an int to get - // it into a vselect significant function - // - if (CI.hasOneUse()) { - User *use = *CI.use_begin(); - if (CallInst *I = dyn_cast(use)) { - if (Function *F = I->getCalledFunction()) { - if (VectorSignificantFunctions::getID(F->getName()) == - VectorSignificantFunctions::vselect) - return; - } + formalArgs.push_back(getRaisedType(CI.getOperand(i)->getType(), length)); + args.push_back(getRaisedOperand(&CI, i)); } } - unsigned length = getVectorLength(&CI); - Value *raisedOp = getRaisedValue(CI.getOperand(0), length); - Instruction *raisedValue = - new CastInst(raisedOp, getRaisedType(CI.getType(), length), "cast", &CI); - setRaisedValue(&CI, raisedValue); - addUsesToWorklist(&CI); - } - - /// Raise a shift instruction - /// - void RaiseVectors::visitShiftInst(ShiftInst &SI) { - Value *raisedOp = getRaisedOperand(&SI, 0); - Instruction *raisedValue = - new ShiftInst(SI.getOpcode(), raisedOp, - SI.getOperand(1), "shift", &SI); - setRaisedValue(&SI, raisedValue); - addUsesToWorklist(&SI); - } - - /// Raise a select instruction - /// - void RaiseVectors::visitSelectInst(SelectInst &SI) { - Value *newOp[2]; - unsigned length = getVectorLength(&SI); - for (unsigned i = 0; i < 2; ++i) { - newOp[i] = getRaisedValue(SI.getOperand(i+1), length); - } - Instruction *raisedValue = - new SelectInst(SI.getOperand(0), newOp[0], newOp[1], - "select", &SI); - setRaisedValue(&SI, raisedValue); - addUsesToWorklist(&SI); - } - - /// Raise a phi node - /// - void RaiseVectors::visitPHINode(PHINode &PN) { - unsigned length = getVectorLength(&PN); - const VectorType *VT = 0; - if (length) - VT = FixedVectorType::get(PN.getType(), length); - else - VT = VectorType::get(PN.getType()); - PHINode *raisedValue = new PHINode(VT, "phi", &PN); - for (unsigned i = 0; i < PN.getNumIncomingValues(); ++i) - raisedValue->addIncoming(getRaisedValue(PN.getIncomingValue(i), length), - PN.getIncomingBlock(i)); - setRaisedValue(&PN, raisedValue); - addUsesToWorklist(&PN); - } - - /// Get the raised type for a given scalar type or pointer to scalar - /// type and vector length. Vector length of 0 means a non-fixed - /// length vector. - /// - const Type *RaiseVectors::getRaisedType(const Type* Ty, unsigned length) { - unsigned i = 0; - while (isa(Ty)) { - Ty = cast(Ty)->getElementType(); - ++i; - } - const Type *result = - (length == 0) ? VectorType::get(Ty) : FixedVectorType::get(Ty, length); - while (i-- > 0) { - result = PointerType::get(result); - } - return result; - } - - /// Get the (fixed) vector length of a raised instruction. Return 0 - /// if the vector is not a fixed-length vector. - /// - unsigned RaiseVectors::getVectorLength(Instruction *I) { - for (User::op_iterator OI = I->op_begin(), OE = I->op_end(); - OI != OE; ++OI) { - if (Value *val = raisingMap[*OI]) { - const Type *Ty = val->getType(); - while (isa(Ty)) - Ty = cast(Ty)->getElementType(); - if (const FixedVectorType *VT = dyn_cast(Ty)) - return VT->getNumElements(); - return 0; + FunctionType *FType = + FunctionType::get(getRaisedType(F->getReturnType(), length), formalArgs, false); + Module *M = CI.getParent()->getParent()->getParent(); + Function *func = M->getOrInsertFunction(name, FType); + raisedValue = new CallInst(func, args, "func", &CI); + addUsesToWorklist(&CI); + break; + } + setRaisedValue(&CI, raisedValue); +} + +/// Raise a binary operator +/// +void RaiseVectors::visitBinaryOperator(BinaryOperator &BO) { + unsigned length = getVectorLength(&BO); + Value *newOp[2]; + for (unsigned i = 0; i < 2; ++i) { + newOp[i] = getRaisedValue(BO.getOperand(i), length); + } + Instruction::BinaryOps raisedOp; + if (SetCondInst *SI = dyn_cast(&BO)) + raisedOp = SI->getVectorOpcode(); + else raisedOp = BO.getOpcode(); + Instruction *raisedValue = + BinaryOperator::create(raisedOp, newOp[0], newOp[1], "binop", &BO); + setRaisedValue(&BO, raisedValue); + addUsesToWorklist(&BO); +} + +/// Raise a cast instruction +/// +void RaiseVectors::visitCastInst(CastInst &CI) { + // Don't raise the cast if it's a cast of a bool to an int to get + // it into a vselect significant function + // + if (CI.hasOneUse()) { + User *use = *CI.use_begin(); + if (CallInst *I = dyn_cast(use)) { + if (Function *F = I->getCalledFunction()) { + if (VectorSignificantFunctions::getID(F->getName()) == + VectorSignificantFunctions::vselect) + return; } } - assert(0 && "Instruction has no raised operands!"); } + unsigned length = getVectorLength(&CI); + Value *raisedOp = getRaisedValue(CI.getOperand(0), length); + Instruction *raisedValue = + new CastInst(raisedOp, getRaisedType(CI.getType(), length), "cast", &CI); + setRaisedValue(&CI, raisedValue); + addUsesToWorklist(&CI); +} - /// Add the specified pair to the raising map, replacing dummy uses - /// if necessary - /// - void RaiseVectors::setRaisedValue(Instruction *key, Value *newValue) { - if (!newValue) - return; - Value*& oldValue = raisingMap[key]; - if (oldValue) { - if (oldValue->getType() != newValue->getType()) - newValue = new CastInst(oldValue, newValue->getType(), "cast", key); - oldValue->replaceAllUsesWith(newValue); - delete oldValue; - } - oldValue = newValue; - } - - /// Get the value for the specified key from the raising map. If no - /// value is there, we haven't raised the value yet, so create a - /// dummy value with the appropriate vector length and replace it - /// when the value is raised. - /// - Value *RaiseVectors::getRaisedValue(Value *key, unsigned length) { - const Type *Ty = getRaisedType(key->getType(), length); - Value*& Val = raisingMap[key]; - if (!Val) { - Val = Ty ? new Argument(Ty) : new Argument(VectorType::get(key->getType())); - DEBUG(std::cerr << "Created dummy value " << *Val << "\n"); - } - return Val; - } - - /// Get the raised operand of an instruction - /// - Value *RaiseVectors::getRaisedOperand(Instruction *I, unsigned i) { - Value *op = I->getOperand(i); - unsigned length = getVectorLength(I); - return getRaisedValue(op, length); - } - - /// Add all uses of an instruction to the worklist - /// - void RaiseVectors::addUsesToWorklist(Instruction *I) { - DEBUG(std::cerr << "Adding uses of " << *I); - for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); - UI != UE; ++UI) { - if (Instruction *II = dyn_cast(*UI)) { - DEBUG(std::cerr << "Adding " << *II); - workList.push_back(II); - } +/// Raise a shift instruction +/// +void RaiseVectors::visitShiftInst(ShiftInst &SI) { + Value *raisedOp = getRaisedOperand(&SI, 0); + Instruction *raisedValue = + new ShiftInst(SI.getOpcode(), raisedOp, + SI.getOperand(1), "shift", &SI); + setRaisedValue(&SI, raisedValue); + addUsesToWorklist(&SI); +} + +/// Raise a select instruction +/// +void RaiseVectors::visitSelectInst(SelectInst &SI) { + Value *newOp[2]; + unsigned length = getVectorLength(&SI); + for (unsigned i = 0; i < 2; ++i) { + newOp[i] = getRaisedValue(SI.getOperand(i+1), length); + } + Instruction *raisedValue = + new SelectInst(SI.getOperand(0), newOp[0], newOp[1], + "select", &SI); + setRaisedValue(&SI, raisedValue); + addUsesToWorklist(&SI); +} + +/// Raise a phi node +/// +void RaiseVectors::visitPHINode(PHINode &PN) { + unsigned length = getVectorLength(&PN); + const VectorType *VT = 0; + if (length) + VT = FixedVectorType::get(PN.getType(), length); + else + VT = VectorType::get(PN.getType()); + PHINode *raisedValue = new PHINode(VT, "phi", &PN); + for (unsigned i = 0; i < PN.getNumIncomingValues(); ++i) + raisedValue->addIncoming(getRaisedValue(PN.getIncomingValue(i), length), + PN.getIncomingBlock(i)); + setRaisedValue(&PN, raisedValue); + addUsesToWorklist(&PN); +} + +/// Get the raised type for a given scalar type or pointer to scalar +/// type and vector length. Vector length of 0 means a non-fixed +/// length vector. +/// +const Type *RaiseVectors::getRaisedType(const Type* Ty, unsigned length) { + unsigned i = 0; + while (isa(Ty)) { + Ty = cast(Ty)->getElementType(); + ++i; + } + const Type *result = + (length == 0) ? VectorType::get(Ty) : FixedVectorType::get(Ty, length); + while (i-- > 0) { + result = PointerType::get(result); + } + return result; +} + +/// Get the (fixed) vector length of a raised instruction. Return 0 +/// if the vector is not a fixed-length vector. +/// +unsigned RaiseVectors::getVectorLength(Instruction *I) { + for (User::op_iterator OI = I->op_begin(), OE = I->op_end(); + OI != OE; ++OI) { + if (Value *val = raisingMap[*OI]) { + const Type *Ty = val->getType(); + while (isa(Ty)) + Ty = cast(Ty)->getElementType(); + if (const FixedVectorType *VT = dyn_cast(Ty)) + return VT->getNumElements(); + return 0; } } + assert(0 && "Instruction has no raised operands!"); +} +/// Add the specified pair to the raising map, replacing dummy uses +/// if necessary +/// +void RaiseVectors::setRaisedValue(Instruction *key, Value *newValue) { + if (!newValue) + return; + Value*& oldValue = raisingMap[key]; + if (oldValue) { + if (oldValue->getType() != newValue->getType()) + newValue = new CastInst(oldValue, newValue->getType(), "cast", key); + oldValue->replaceAllUsesWith(newValue); + delete oldValue; + } + oldValue = newValue; } + +/// Get the value for the specified key from the raising map. If no +/// value is there, we haven't raised the value yet, so create a +/// dummy value with the appropriate vector length and replace it +/// when the value is raised. +/// +Value *RaiseVectors::getRaisedValue(Value *key, unsigned length) { + const Type *Ty = getRaisedType(key->getType(), length); + Value*& Val = raisingMap[key]; + if (!Val) { + Val = Ty ? new Argument(Ty) : new Argument(VectorType::get(key->getType())); + DEBUG(std::cerr << "Created dummy value " << *Val << "\n"); + } + return Val; +} + +/// Get the raised operand of an instruction +/// +Value *RaiseVectors::getRaisedOperand(Instruction *I, unsigned i) { + Value *op = I->getOperand(i); + unsigned length = getVectorLength(I); + return getRaisedValue(op, length); +} + +/// Add all uses of an instruction to the worklist +/// +void RaiseVectors::addUsesToWorklist(Instruction *I) { + DEBUG(std::cerr << "Adding uses of " << *I); + for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); + UI != UE; ++UI) { + if (Instruction *II = dyn_cast(*UI)) { + DEBUG(std::cerr << "Adding " << *II); + workList.push_back(II); + } + } +} + + + Index: llvm/lib/Transforms/Vector/SSE.cpp diff -u llvm/lib/Transforms/Vector/SSE.cpp:1.1.2.2 llvm/lib/Transforms/Vector/SSE.cpp:1.1.2.3 --- llvm/lib/Transforms/Vector/SSE.cpp:1.1.2.2 Tue Nov 15 14:15:33 2005 +++ llvm/lib/Transforms/Vector/SSE.cpp Wed Nov 16 12:32:56 2005 @@ -27,6 +27,7 @@ #include "llvm/ADT/hash_set" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/InstVisitor.h" +#include "llvm/Transforms/Scalar.h" using namespace llvm; @@ -516,3 +517,5 @@ } } + +FunctionPass *llvm::createSSEPass() { return new SSE(); } From bocchino at cs.uiuc.edu Wed Nov 16 12:33:16 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:16 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Transforms/Instrumentation/ProfilePaths/CombineBranch.cpp EdgeCode.cpp Graph.cpp Graph.h GraphAuxiliary.cpp InstLoops.cpp Makefile ProfilePaths.cpp RetracePath.cpp Message-ID: <200511161833.MAA21359@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Instrumentation/ProfilePaths: CombineBranch.cpp (r1.15) removed EdgeCode.cpp (r1.30) removed Graph.cpp (r1.21) removed Graph.h (r1.14) removed GraphAuxiliary.cpp (r1.28) removed InstLoops.cpp (r1.21) removed Makefile (r1.6) removed ProfilePaths.cpp (r1.43) removed RetracePath.cpp (r1.13) removed --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+0 -0) 0 files changed From bocchino at cs.uiuc.edu Wed Nov 16 12:33:12 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:12 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/VMCore/AsmWriter.cpp Function.cpp Instructions.cpp Mangler.cpp SymbolTable.cpp Type.cpp Verifier.cpp Message-ID: <200511161833.MAA21323@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AsmWriter.cpp updated: 1.181.2.1 -> 1.181.2.2 Function.cpp updated: 1.95 -> 1.95.4.1 Instructions.cpp updated: 1.26.2.1 -> 1.26.2.2 Mangler.cpp updated: 1.19 -> 1.19.2.1 SymbolTable.cpp updated: 1.59 -> 1.59.4.1 Type.cpp updated: 1.129.2.1 -> 1.129.2.2 Verifier.cpp updated: 1.134.2.1 -> 1.134.2.2 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+270 -220) AsmWriter.cpp | 15 ++- Function.cpp | 7 - Instructions.cpp | 14 +- Mangler.cpp | 171 +++++++++++++++++++++++----------- SymbolTable.cpp | 2 Type.cpp | 273 +++++++++++++++++++++++-------------------------------- Verifier.cpp | 8 + 7 files changed, 270 insertions(+), 220 deletions(-) Index: llvm/lib/VMCore/AsmWriter.cpp diff -u llvm/lib/VMCore/AsmWriter.cpp:1.181.2.1 llvm/lib/VMCore/AsmWriter.cpp:1.181.2.2 --- llvm/lib/VMCore/AsmWriter.cpp:1.181.2.1 Tue Oct 18 14:21:57 2005 +++ llvm/lib/VMCore/AsmWriter.cpp Wed Nov 16 12:32:57 2005 @@ -839,7 +839,12 @@ assert(C && "GlobalVar initializer isn't constant?"); writeOperand(GV->getInitializer(), false, isa(C)); } - + + if (GV->hasSection()) + Out << ", section \"" << GV->getSection() << '"'; + if (GV->getAlignment()) + Out << ", align " << GV->getAlignment(); + printInfoComment(*GV); Out << "\n"; } @@ -947,6 +952,11 @@ } Out << ')'; + if (F->hasSection()) + Out << " section \"" << F->getSection() << '"'; + if (F->getAlignment()) + Out << " align " << F->getAlignment(); + if (F->isExternal()) { Out << "\n"; } else { @@ -1181,6 +1191,9 @@ Out << ','; writeOperand(AI->getArraySize(), true); } + if (AI->getAlignment()) { + Out << ", align " << AI->getAlignment(); + } } else if (isa(I)) { if (Operand) writeOperand(Operand, true); // Work with broken code Out << " to "; Index: llvm/lib/VMCore/Function.cpp diff -u llvm/lib/VMCore/Function.cpp:1.95 llvm/lib/VMCore/Function.cpp:1.95.4.1 --- llvm/lib/VMCore/Function.cpp:1.95 Fri May 6 15:26:43 2005 +++ llvm/lib/VMCore/Function.cpp Wed Nov 16 12:32:58 2005 @@ -243,9 +243,10 @@ if (getName() == "llvm.pcmarker") return Intrinsic::pcmarker; break; case 'r': - if (getName() == "llvm.returnaddress") return Intrinsic::returnaddress; - if (getName() == "llvm.readport") return Intrinsic::readport; - if (getName() == "llvm.readio") return Intrinsic::readio; + if (getName() == "llvm.returnaddress") return Intrinsic::returnaddress; + if (getName() == "llvm.readport") return Intrinsic::readport; + if (getName() == "llvm.readio") return Intrinsic::readio; + if (getName() == "llvm.readcyclecounter") return Intrinsic::readcyclecounter; break; case 's': if (getName() == "llvm.setjmp") return Intrinsic::setjmp; Index: llvm/lib/VMCore/Instructions.cpp diff -u llvm/lib/VMCore/Instructions.cpp:1.26.2.1 llvm/lib/VMCore/Instructions.cpp:1.26.2.2 --- llvm/lib/VMCore/Instructions.cpp:1.26.2.1 Tue Oct 18 14:21:57 2005 +++ llvm/lib/VMCore/Instructions.cpp Wed Nov 16 12:32:58 2005 @@ -495,18 +495,20 @@ } AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, - const std::string &Name, + unsigned Align, const std::string &Name, Instruction *InsertBefore) : UnaryInstruction(PointerType::get(Ty), iTy, getAISize(ArraySize), - Name, InsertBefore) { + Name, InsertBefore), Alignment(Align) { + assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); assert(Ty != Type::VoidTy && "Cannot allocate void!"); } AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, - const std::string &Name, + unsigned Align, const std::string &Name, BasicBlock *InsertAtEnd) : UnaryInstruction(PointerType::get(Ty), iTy, getAISize(ArraySize), - Name, InsertAtEnd) { + Name, InsertAtEnd), Alignment(Align) { + assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); assert(Ty != Type::VoidTy && "Cannot allocate void!"); } @@ -522,12 +524,12 @@ AllocaInst::AllocaInst(const AllocaInst &AI) : AllocationInst(AI.getType()->getElementType(), (Value*)AI.getOperand(0), - Instruction::Alloca) { + Instruction::Alloca, AI.getAlignment()) { } MallocInst::MallocInst(const MallocInst &MI) : AllocationInst(MI.getType()->getElementType(), (Value*)MI.getOperand(0), - Instruction::Malloc) { + Instruction::Malloc, MI.getAlignment()) { } //===----------------------------------------------------------------------===// Index: llvm/lib/VMCore/Mangler.cpp diff -u llvm/lib/VMCore/Mangler.cpp:1.19 llvm/lib/VMCore/Mangler.cpp:1.19.2.1 --- llvm/lib/VMCore/Mangler.cpp:1.19 Thu Oct 13 20:28:34 2005 +++ llvm/lib/VMCore/Mangler.cpp Wed Nov 16 12:32:58 2005 @@ -12,8 +12,8 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/Mangler.h" +#include "llvm/DerivedTypes.h" #include "llvm/Module.h" -#include "llvm/Type.h" #include "llvm/ADT/StringExtras.h" using namespace llvm; @@ -22,7 +22,8 @@ } static std::string MangleLetter(unsigned char C) { - return std::string("_")+HexDigit(C >> 4) + HexDigit(C & 15) + "_"; + char Result[] = { '_', HexDigit(C >> 4), HexDigit(C & 15), '_', 0 }; + return Result; } /// makeNameProper - We don't want identifier names non-C-identifier characters @@ -30,24 +31,71 @@ /// std::string Mangler::makeNameProper(const std::string &X, const char *Prefix) { std::string Result; - - // If X does not start with (char)1, add the prefix. - std::string::const_iterator I = X.begin(); - if (*I != 1) - Result = Prefix; - else - ++I; // Skip over the marker. + if (X.empty()) return X; // Empty names are uniqued by the caller. - // Mangle the first letter specially, don't allow numbers... - if (*I >= '0' && *I <= '9') - Result += MangleLetter(*I++); - - for (std::string::const_iterator E = X.end(); I != E; ++I) - if ((*I < 'a' || *I > 'z') && (*I < 'A' || *I > 'Z') && - (*I < '0' || *I > '9') && *I != '_' && *I != '$') - Result += MangleLetter(*I); + if (!UseQuotes) { + // If X does not start with (char)1, add the prefix. + std::string::const_iterator I = X.begin(); + if (*I != 1) + Result = Prefix; + else + ++I; // Skip over the marker. + + // Mangle the first letter specially, don't allow numbers. + if (*I >= '0' && *I <= '9') + Result += MangleLetter(*I++); + + for (std::string::const_iterator E = X.end(); I != E; ++I) { + if (!isCharAcceptable(*I)) + Result += MangleLetter(*I); + else + Result += *I; + } + } else { + bool NeedsQuotes = false; + + std::string::const_iterator I = X.begin(); + if (*I == 1) + ++I; // Skip over the marker. + + // If the first character is a number, we need quotes. + if (*I >= '0' && *I <= '9') + NeedsQuotes = true; + + // Do an initial scan of the string, checking to see if we need quotes or + // to escape a '"' or not. + if (!NeedsQuotes) + for (std::string::const_iterator E = X.end(); I != E; ++I) + if (!isCharAcceptable(*I)) { + NeedsQuotes = true; + break; + } + + // In the common case, we don't need quotes. Handle this quickly. + if (!NeedsQuotes) { + if (*X.begin() != 1) + return Prefix+X; + else + return X.substr(1); + } + + // Otherwise, construct the string the expensive way. + I = X.begin(); + + // If X does not start with (char)1, add the prefix. + if (*I != 1) + Result = Prefix; else - Result += *I; + ++I; // Skip the marker if present. + + for (std::string::const_iterator E = X.end(); I != E; ++I) { + if (*I == '"') + Result += "_QQ_"; + else + Result += *I; + } + Result = '"' + Result + '"'; + } return Result; } @@ -59,48 +107,50 @@ return E; } - std::string Mangler::getValueName(const Value *V) { - // Check to see whether we've already named V. - ValueMap::iterator VI = Memo.find(V); - if (VI != Memo.end()) { - return VI->second; // Return the old name for V. - } + if (const GlobalValue *GV = dyn_cast(V)) + return getValueName(GV); + + std::string &Name = Memo[V]; + if (!Name.empty()) + return Name; // Return the already-computed name for V. + + // Always mangle local names. + Name = "ltmp_" + utostr(Count++) + "_" + utostr(getTypeID(V->getType())); + return Name; +} - std::string name; - if (V->hasName()) { // Print out the label if it exists... - // Name mangling occurs as follows: - // - If V is an intrinsic function, do not change name at all - // - If V is not a global, mangling always occurs. - // - Otherwise, mangling occurs when any of the following are true: - // 1) V has internal linkage - // 2) V's name would collide if it is not mangled. - // - const GlobalValue* gv = dyn_cast(V); - if (gv && isa(gv) && cast(gv)->getIntrinsicID()) { - name = gv->getName(); // Is an intrinsic function - } else if (gv && !gv->hasInternalLinkage() && !MangledGlobals.count(gv)) { - name = makeNameProper(gv->getName(), Prefix); - } else { - // Non-global, or global with internal linkage / colliding name - // -> mangle. - unsigned TypeUniqueID = getTypeID(V->getType()); - name = "l" + utostr(TypeUniqueID) + "_" + makeNameProper(V->getName()); - } + +std::string Mangler::getValueName(const GlobalValue *GV) { + // Check to see whether we've already named V. + std::string &Name = Memo[GV]; + if (!Name.empty()) + return Name; // Return the already-computed name for V. + + // Name mangling occurs as follows: + // - If V is an intrinsic function, do not change name at all + // - Otherwise, mangling occurs if global collides with existing name. + if (isa(GV) && cast(GV)->getIntrinsicID()) { + Name = GV->getName(); // Is an intrinsic function + } else if (!GV->hasName()) { + // Must mangle the global into a unique ID. + unsigned TypeUniqueID = getTypeID(GV->getType()); + static unsigned GlobalID = 0; + Name = "__unnamed_" + utostr(TypeUniqueID) + "_" + utostr(GlobalID++); + } else if (!MangledGlobals.count(GV)) { + Name = makeNameProper(GV->getName(), Prefix); } else { - name = "ltmp_" + utostr(Count++) + "_" + utostr(getTypeID(V->getType())); + unsigned TypeUniqueID = getTypeID(GV->getType()); + Name = "l" + utostr(TypeUniqueID) + "_" + makeNameProper(GV->getName()); } - Memo[V] = name; - return name; + return Name; } void Mangler::InsertName(GlobalValue *GV, std::map &Names) { - if (!GV->hasName()) { // We must mangle unnamed globals. - MangledGlobals.insert(GV); + if (!GV->hasName()) // We must mangle unnamed globals. return; - } // Figure out if this is already used. GlobalValue *&ExistingValue = Names[GV->getName()]; @@ -119,8 +169,25 @@ } -Mangler::Mangler(Module &m, const char *prefix) - : M(m), Prefix(prefix), TypeCounter(0), Count(0) { +Mangler::Mangler(Module &M, const char *prefix) + : Prefix(prefix), UseQuotes(false), Count(0), TypeCounter(0) { + std::fill(AcceptableChars, + AcceptableChars+sizeof(AcceptableChars)/sizeof(AcceptableChars[0]), + 0); + + // Letters and numbers are acceptable. + for (unsigned char X = 'a'; X <= 'z'; ++X) + markCharAcceptable(X); + for (unsigned char X = 'A'; X <= 'Z'; ++X) + markCharAcceptable(X); + for (unsigned char X = '0'; X <= '9'; ++X) + markCharAcceptable(X); + + // These chars are acceptable. + markCharAcceptable('_'); + markCharAcceptable('$'); + markCharAcceptable('.'); + // Calculate which global values have names that will collide when we throw // away type information. std::map Names; Index: llvm/lib/VMCore/SymbolTable.cpp diff -u llvm/lib/VMCore/SymbolTable.cpp:1.59 llvm/lib/VMCore/SymbolTable.cpp:1.59.4.1 --- llvm/lib/VMCore/SymbolTable.cpp:1.59 Thu Apr 21 18:46:51 2005 +++ llvm/lib/VMCore/SymbolTable.cpp Wed Nov 16 12:32:58 2005 @@ -269,12 +269,12 @@ value_iterator B = Plane.begin(), Bend = Plane.end(); while (B != Bend) { // Found nonempty type plane! Value *V = B->second; + ++B; if (!isa(V) || cast(V)->hasInternalLinkage()) { // Set name to "", removing from symbol table! V->setName(""); RemovedSymbol = true; } - ++B; } } Index: llvm/lib/VMCore/Type.cpp diff -u llvm/lib/VMCore/Type.cpp:1.129.2.1 llvm/lib/VMCore/Type.cpp:1.129.2.2 --- llvm/lib/VMCore/Type.cpp:1.129.2.1 Tue Oct 18 14:21:58 2005 +++ llvm/lib/VMCore/Type.cpp Wed Nov 16 12:32:58 2005 @@ -19,6 +19,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/SCCIterator.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/MathExtras.h" #include #include using namespace llvm; @@ -42,14 +43,13 @@ static std::map ConcreteTypeDescriptions; static std::map AbstractTypeDescriptions; -Type::Type( const std::string& name, TypeID id ) - : RefCount(0), ForwardType(0) { - if (!name.empty()) - ConcreteTypeDescriptions[this] = name; - ID = id; - Abstract = false; +Type::Type(const char *Name, TypeID id) + : ID(id), Abstract(false), RefCount(0), ForwardType(0) { + assert(Name && Name[0] && "Should use other ctor if no name!"); + ConcreteTypeDescriptions[this] = Name; } + const Type *Type::getPrimitiveType(TypeID IDNumber) { switch (IDNumber) { case VoidTyID : return VoidTy; @@ -213,6 +213,14 @@ return ForwardType; } +void Type::refineAbstractType(const DerivedType *OldTy, const Type *NewTy) { + abort(); +} +void Type::typeBecameConcrete(const DerivedType *AbsTy) { + abort(); +} + + // getTypeDescription - This is a recursive function that walks a type hierarchy // calculating the description for a type. // @@ -291,12 +299,6 @@ Result += getTypeDescription(ATy->getElementType(), TypeStack) + "]"; break; } - case Type::StreamTyID: { - const StreamType *STy = cast(Ty); - Result = "[stream of "; - Result += getTypeDescription(STy->getElementType(), TypeStack) + "]"; - break; - } case Type::VectorTyID: { const VectorType *VTy = cast(Ty); Result = "[vector of "; @@ -453,12 +455,6 @@ setAbstract(E->isAbstract()); } -StreamType::StreamType(const Type *E) - : SequentialType(StreamTyID, E) { - assert((E->isIntegral() || E->isFloatingPoint() || isa(E)) && - "Elements of a StreamType must be a primitive or fixed vector type!"); -} - VectorType::VectorType(const Type *E, bool fixed) : SequentialType(fixed ? FixedVectorTyID : VectorTyID, E) { assert((E->isIntegral() || E->isFloatingPoint()) && @@ -697,15 +693,9 @@ // Derived Type Factory Functions //===----------------------------------------------------------------------===// -// TypeMap - Make sure that only one instance of a particular type may be -// created on any given run of the compiler... note that this involves updating -// our map if an abstract type gets refined somehow. -// namespace llvm { -template -class TypeMap { - std::map Map; - +class TypeMapBase { +protected: /// TypesByHash - Keep track of types by their structure hash value. Note /// that we only keep track of types that have cycles through themselves in /// this map. @@ -714,14 +704,48 @@ friend void Type::clearAllTypeMaps(); -private: - void clear(std::vector &DerivedTypes) { - for (typename std::map::iterator I = Map.begin(), - E = Map.end(); I != E; ++I) - DerivedTypes.push_back(I->second.get()); - TypesByHash.clear(); - Map.clear(); +public: + void RemoveFromTypesByHash(unsigned Hash, const Type *Ty) { + std::multimap::iterator I = + TypesByHash.lower_bound(Hash); + while (I->second != Ty) { + ++I; + assert(I != TypesByHash.end() && I->first == Hash); + } + TypesByHash.erase(I); + } + + /// TypeBecameConcrete - When Ty gets a notification that TheType just became + /// concrete, drop uses and make Ty non-abstract if we should. + void TypeBecameConcrete(DerivedType *Ty, const DerivedType *TheType) { + // If the element just became concrete, remove 'ty' from the abstract + // type user list for the type. Do this for as many times as Ty uses + // OldType. + for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); + I != E; ++I) + if (I->get() == TheType) + TheType->removeAbstractTypeUser(Ty); + + // If the type is currently thought to be abstract, rescan all of our + // subtypes to see if the type has just become concrete! Note that this + // may send out notifications to AbstractTypeUsers that types become + // concrete. + if (Ty->isAbstract()) + Ty->PromoteAbstractToConcrete(); } +}; +} + + +// TypeMap - Make sure that only one instance of a particular type may be +// created on any given run of the compiler... note that this involves updating +// our map if an abstract type gets refined somehow. +// +namespace llvm { +template +class TypeMap : public TypeMapBase { + std::map Map; + public: typedef typename std::map::iterator iterator; ~TypeMap() { print("ON EXIT"); } @@ -738,29 +762,29 @@ TypesByHash.insert(std::make_pair(ValType::hashTypeStructure(Ty), Ty)); print("add"); } - - void RemoveFromTypesByHash(unsigned Hash, const Type *Ty) { - std::multimap::iterator I = - TypesByHash.lower_bound(Hash); - while (I->second != Ty) { - ++I; - assert(I != TypesByHash.end() && I->first == Hash); - } - TypesByHash.erase(I); + + void clear(std::vector &DerivedTypes) { + for (typename std::map::iterator I = Map.begin(), + E = Map.end(); I != E; ++I) + DerivedTypes.push_back(I->second.get()); + TypesByHash.clear(); + Map.clear(); } - /// finishRefinement - This method is called after we have updated an existing - /// type with its new components. We must now either merge the type away with + /// RefineAbstractType - This method is called after we have merged a type + /// with another one. We must now either merge the type away with /// some other type or reinstall it in the map with it's new configuration. - /// The specified iterator tells us what the type USED to look like. - void finishRefinement(TypeClass *Ty, const DerivedType *OldType, + void RefineAbstractType(TypeClass *Ty, const DerivedType *OldType, const Type *NewType) { - assert((Ty->isAbstract() || !OldType->isAbstract()) && - "Refining a non-abstract type!"); #ifdef DEBUG_MERGE_TYPES - std::cerr << "refineAbstractTy(" << (void*)OldType << "[" << *OldType - << "], " << (void*)NewType << " [" << *NewType << "])\n"; + std::cerr << "RefineAbstractType(" << (void*)OldType << "[" << *OldType + << "], " << (void*)NewType << " [" << *NewType << "])\n"; #endif + + // Otherwise, we are changing one subelement type into another. Clearly the + // OldType must have been abstract, making us abstract. + assert(Ty->isAbstract() && "Refining a non-abstract type!"); + assert(OldType != NewType); // Make a temporary type holder for the type so that it doesn't disappear on // us when we erase the entry from the map. @@ -768,7 +792,8 @@ // The old record is now out-of-date, because one of the children has been // updated. Remove the obsolete entry from the map. - Map.erase(ValType::get(Ty)); + unsigned NumErased = Map.erase(ValType::get(Ty)); + assert(NumErased && "Element not found!"); // Remember the structural hash for the type before we start hacking on it, // in case we need it later. @@ -776,25 +801,22 @@ // Find the type element we are refining... and change it now! for (unsigned i = 0, e = Ty->ContainedTys.size(); i != e; ++i) - if (Ty->ContainedTys[i] == OldType) { - Ty->ContainedTys[i].removeUserFromConcrete(); + if (Ty->ContainedTys[i] == OldType) Ty->ContainedTys[i] = NewType; - } - - unsigned TypeHash = ValType::hashTypeStructure(Ty); - + unsigned NewTypeHash = ValType::hashTypeStructure(Ty); + // If there are no cycles going through this node, we can do a simple, // efficient lookup in the map, instead of an inefficient nasty linear // lookup. - if (!Ty->isAbstract() || !TypeHasCycleThroughItself(Ty)) { + if (!TypeHasCycleThroughItself(Ty)) { typename std::map::iterator I; bool Inserted; - ValType V = ValType::get(Ty); - tie(I, Inserted) = Map.insert(std::make_pair(V, Ty)); + tie(I, Inserted) = Map.insert(std::make_pair(ValType::get(Ty), Ty)); if (!Inserted) { + assert(OldType != NewType); // Refined to a different type altogether? - RemoveFromTypesByHash(TypeHash, Ty); + RemoveFromTypesByHash(OldTypeHash, Ty); // We already have this type in the table. Get rid of the newly refined // type. @@ -802,7 +824,6 @@ Ty->refineAbstractTypeTo(NewTy); return; } - } else { // Now we check to see if there is an existing entry in the table which is // structurally identical to the newly refined type. If so, this type @@ -812,44 +833,44 @@ tie(I, E) = TypesByHash.equal_range(OldTypeHash); Entry = E; for (; I != E; ++I) { - if (I->second != Ty) { + if (I->second == Ty) { + // Remember the position of the old type if we see it in our scan. + Entry = I; + } else { if (TypesEqual(Ty, I->second)) { - assert(Ty->isAbstract() && "Replacing a non-abstract type?"); TypeClass *NewTy = cast((Type*)I->second.get()); if (Entry == E) { - // Find the location of Ty in the TypesByHash structure. + // Find the location of Ty in the TypesByHash structure if we + // haven't seen it already. while (I->second != Ty) { ++I; assert(I != E && "Structure doesn't contain type??"); } Entry = I; } - TypesByHash.erase(Entry); Ty->refineAbstractTypeTo(NewTy); return; } - } else { - // Remember the position of - Entry = I; } } - // If there is no existing type of the same structure, we reinsert an // updated record into the map. Map.insert(std::make_pair(ValType::get(Ty), Ty)); } // If the hash codes differ, update TypesByHash - if (TypeHash != OldTypeHash) { + if (NewTypeHash != OldTypeHash) { RemoveFromTypesByHash(OldTypeHash, Ty); - TypesByHash.insert(std::make_pair(TypeHash, Ty)); + TypesByHash.insert(std::make_pair(NewTypeHash, Ty)); } - + // If the type is currently thought to be abstract, rescan all of our - // subtypes to see if the type has just become concrete! + // subtypes to see if the type has just become concrete! Note that this + // may send out notifications to AbstractTypeUsers that types become + // concrete. if (Ty->isAbstract()) Ty->PromoteAbstractToConcrete(); } @@ -1025,6 +1046,7 @@ FixedVectorType *FixedVectorType::get(const Type *ElementType, unsigned NumElements) { assert(ElementType && "Can't get fixed-length vector of null types!"); + //assert(isPowerOf2_32(NumElements) && "Vector length should be a power of 2!"); FixedVectorValType PVT(ElementType, NumElements); FixedVectorType *PT = FixedVectorTypes.get(PVT); @@ -1148,7 +1170,6 @@ return PT; } - //===----------------------------------------------------------------------===// // Vector Type Factory... // @@ -1198,54 +1219,6 @@ //===----------------------------------------------------------------------===// -// Stream Type Factory... -// -namespace llvm { -class StreamValType { - const Type *ValTy; -public: - StreamValType(const Type *val) : ValTy(val) {} - - static StreamValType get(const StreamType *AT) { - return StreamValType(AT->getElementType()); - } - - static unsigned hashTypeStructure(const StreamType *AT) { - return AT->getElementType()->getTypeID(); // ??? - } - - // Subclass should override this... to update self as usual - void doRefinement(const DerivedType *OldType, const Type *NewType) { - assert(ValTy == OldType); - ValTy = NewType; - } - - inline bool operator<(const StreamValType &MTV) const { - return ValTy < MTV.ValTy; - } -}; -} - -static TypeMap StreamTypes; - -StreamType *StreamType::get(const Type *ElementType) { - assert(ElementType && "Can't get vector of null types!"); - - StreamValType AVT(ElementType); - StreamType *AT = StreamTypes.get(AVT); - if (AT) return AT; // Found a match, return it! - - // Value not found. Derive a new type! - StreamTypes.add(AVT, AT = new StreamType(ElementType)); - -#ifdef DEBUG_MERGE_TYPES - std::cerr << "Derived new type: " << *AT << "\n"; -#endif - return AT; -} - - -//===----------------------------------------------------------------------===// // Derived Type Refinement Functions //===----------------------------------------------------------------------===// @@ -1254,7 +1227,7 @@ // the PATypeHandle class. When there are no users of the abstract type, it // is annihilated, because there is no way to get a reference to it ever again. // -void DerivedType::removeAbstractTypeUser(AbstractTypeUser *U) const { +void Type::removeAbstractTypeUser(AbstractTypeUser *U) const { // Search from back to front because we will notify users from back to // front. Also, it is likely that there will be a stack like behavior to // users that register and unregister users. @@ -1379,11 +1352,11 @@ // void FunctionType::refineAbstractType(const DerivedType *OldType, const Type *NewType) { - FunctionTypes.finishRefinement(this, OldType, NewType); + FunctionTypes.RefineAbstractType(this, OldType, NewType); } void FunctionType::typeBecameConcrete(const DerivedType *AbsTy) { - refineAbstractType(AbsTy, AbsTy); + FunctionTypes.TypeBecameConcrete(this, AbsTy); } @@ -1393,24 +1366,33 @@ // void ArrayType::refineAbstractType(const DerivedType *OldType, const Type *NewType) { - ArrayTypes.finishRefinement(this, OldType, NewType); + ArrayTypes.RefineAbstractType(this, OldType, NewType); } void ArrayType::typeBecameConcrete(const DerivedType *AbsTy) { - refineAbstractType(AbsTy, AbsTy); + ArrayTypes.TypeBecameConcrete(this, AbsTy); } // refineAbstractType - Called when a contained type is found to be more // concrete - this could potentially change us from an abstract type to a // concrete type. // +void VectorType::refineAbstractType(const DerivedType *OldType, + const Type *NewType) { + VectorTypes.RefineAbstractType(this, OldType, NewType); +} + +void VectorType::typeBecameConcrete(const DerivedType *AbsTy) { + VectorTypes.TypeBecameConcrete(this, AbsTy); +} + void FixedVectorType::refineAbstractType(const DerivedType *OldType, const Type *NewType) { - FixedVectorTypes.finishRefinement(this, OldType, NewType); + FixedVectorTypes.RefineAbstractType(this, OldType, NewType); } void FixedVectorType::typeBecameConcrete(const DerivedType *AbsTy) { - refineAbstractType(AbsTy, AbsTy); + FixedVectorTypes.TypeBecameConcrete(this, AbsTy); } // refineAbstractType - Called when a contained type is found to be more @@ -1419,11 +1401,11 @@ // void StructType::refineAbstractType(const DerivedType *OldType, const Type *NewType) { - StructTypes.finishRefinement(this, OldType, NewType); + StructTypes.RefineAbstractType(this, OldType, NewType); } void StructType::typeBecameConcrete(const DerivedType *AbsTy) { - refineAbstractType(AbsTy, AbsTy); + StructTypes.TypeBecameConcrete(this, AbsTy); } // refineAbstractType - Called when a contained type is found to be more @@ -1432,24 +1414,11 @@ // void PointerType::refineAbstractType(const DerivedType *OldType, const Type *NewType) { - PointerTypes.finishRefinement(this, OldType, NewType); + PointerTypes.RefineAbstractType(this, OldType, NewType); } void PointerType::typeBecameConcrete(const DerivedType *AbsTy) { - refineAbstractType(AbsTy, AbsTy); -} - -// refineAbstractType - Called when a contained type is found to be more -// concrete - this could potentially change us from an abstract type to a -// concrete type. -// -void VectorType::refineAbstractType(const DerivedType *OldType, - const Type *NewType) { - VectorTypes.finishRefinement(this, OldType, NewType); -} - -void VectorType::typeBecameConcrete(const DerivedType *AbsTy) { - refineAbstractType(AbsTy, AbsTy); + PointerTypes.TypeBecameConcrete(this, AbsTy); } @@ -1457,15 +1426,6 @@ // concrete - this could potentially change us from an abstract type to a // concrete type. // -void StreamType::refineAbstractType(const DerivedType *OldType, - const Type *NewType) { - StreamTypes.finishRefinement(this, OldType, NewType); -} - -void StreamType::typeBecameConcrete(const DerivedType *AbsTy) { - refineAbstractType(AbsTy, AbsTy); -} - bool SequentialType::indexValid(const Value *V) const { const Type *Ty = V->getType(); @@ -1505,7 +1465,6 @@ PointerTypes.clear(DerivedTypes); StructTypes.clear(DerivedTypes); ArrayTypes.clear(DerivedTypes); - StreamTypes.clear(DerivedTypes); VectorTypes.clear(DerivedTypes); FixedVectorTypes.clear(DerivedTypes); Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.134.2.1 llvm/lib/VMCore/Verifier.cpp:1.134.2.2 --- llvm/lib/VMCore/Verifier.cpp:1.134.2.1 Tue Oct 18 14:21:58 2005 +++ llvm/lib/VMCore/Verifier.cpp Wed Nov 16 12:32:58 2005 @@ -733,6 +733,14 @@ NumArgs = 2; break; + case Intrinsic::readcyclecounter: + Assert1(FT->getNumParams() == 0, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType() == Type::ULongTy, + "Return type is not ulong!", IF); + NumArgs = 0; + break; + case Intrinsic::ctpop: case Intrinsic::ctlz: case Intrinsic::cttz: From bocchino at cs.uiuc.edu Wed Nov 16 12:33:20 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:20 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/test/Feature/alignment.ll global_section.ll Message-ID: <200511161833.MAA21379@zion.cs.uiuc.edu> Changes in directory llvm/test/Feature: alignment.ll added (r1.2.2.2) global_section.ll added (r1.1.2.2) --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+29 -0) alignment.ll | 19 +++++++++++++++++++ global_section.ll | 10 ++++++++++ 2 files changed, 29 insertions(+) Index: llvm/test/Feature/alignment.ll diff -c /dev/null llvm/test/Feature/alignment.ll:1.2.2.2 *** /dev/null Wed Nov 16 12:33:18 2005 --- llvm/test/Feature/alignment.ll Wed Nov 16 12:33:08 2005 *************** *** 0 **** --- 1,19 ---- + ; RUN: llvm-as %s -o - | llvm-dis > %t1.ll + ; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll + ; RUN: diff %t1.ll %t2.ll + + %X = global int 4, align 16 + + int *%test() align 32 { + %X = alloca int, align 4 + %Y = alloca int, uint 42, align 16 + %Z = alloca int, align 0 + ret int *%X + } + + int *%test2() { + %X = malloc int, align 4 + %Y = malloc int, uint 42, align 16 + %Z = malloc int, align 0 + ret int *%X + } Index: llvm/test/Feature/global_section.ll diff -c /dev/null llvm/test/Feature/global_section.ll:1.1.2.2 *** /dev/null Wed Nov 16 12:33:20 2005 --- llvm/test/Feature/global_section.ll Wed Nov 16 12:33:08 2005 *************** *** 0 **** --- 1,10 ---- + ; RUN: llvm-as %s -o - | llvm-dis > %t1.ll + ; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll + ; RUN: diff %t1.ll %t2.ll + + %X = global int 4, section "foo", align 16 + + void %test() section "bar" { + ret void + } + From bocchino at cs.uiuc.edu Wed Nov 16 12:33:12 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:12 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/lib/Transforms/Scalar/ADCE.cpp InstructionCombining.cpp LoopStrengthReduce.cpp LowerAllocations.cpp LowerConstantExprs.cpp LowerGC.cpp LowerInvoke.cpp Makefile Reg2Mem.cpp ScalarReplAggregates.cpp TailRecursionElimination.cpp Message-ID: <200511161833.MAA21281@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: ADCE.cpp updated: 1.93 -> 1.93.4.1 InstructionCombining.cpp updated: 1.388.2.1 -> 1.388.2.2 LoopStrengthReduce.cpp updated: 1.68 -> 1.68.2.1 LowerAllocations.cpp updated: 1.54 -> 1.54.4.1 LowerConstantExprs.cpp (r1.4.4.1) removed LowerGC.cpp updated: 1.8 -> 1.8.4.1 LowerInvoke.cpp updated: 1.33 -> 1.33.2.1 Makefile updated: 1.4 -> 1.4.6.1 Reg2Mem.cpp added (r1.3.2.2) ScalarReplAggregates.cpp updated: 1.31 -> 1.31.4.1 TailRecursionElimination.cpp updated: 1.21 -> 1.21.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+323 -63) ADCE.cpp | 2 InstructionCombining.cpp | 257 +++++++++++++++++++++++++++++++++++-------- LoopStrengthReduce.cpp | 3 LowerAllocations.cpp | 2 LowerGC.cpp | 5 LowerInvoke.cpp | 29 ++-- Makefile | 1 Reg2Mem.cpp | 81 +++++++++++++ ScalarReplAggregates.cpp | 5 TailRecursionElimination.cpp | 1 10 files changed, 323 insertions(+), 63 deletions(-) Index: llvm/lib/Transforms/Scalar/ADCE.cpp diff -u llvm/lib/Transforms/Scalar/ADCE.cpp:1.93 llvm/lib/Transforms/Scalar/ADCE.cpp:1.93.4.1 --- llvm/lib/Transforms/Scalar/ADCE.cpp:1.93 Sat May 14 07:25:31 2005 +++ llvm/lib/Transforms/Scalar/ADCE.cpp Wed Nov 16 12:32:53 2005 @@ -29,6 +29,8 @@ #include using namespace llvm; +static IncludeFile X((void*)createUnifyFunctionExitNodesPass); + namespace { Statistic<> NumBlockRemoved("adce", "Number of basic blocks removed"); Statistic<> NumInstRemoved ("adce", "Number of instructions removed"); Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.388.2.1 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.388.2.2 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.388.2.1 Tue Oct 18 14:21:57 2005 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Wed Nov 16 12:32:53 2005 @@ -227,6 +227,7 @@ bool isSub, Instruction &I); Instruction *InsertRangeTest(Value *V, Constant *Lo, Constant *Hi, bool Inside, Instruction &IB); + Instruction *PromoteCastOfAllocation(CastInst &CI, AllocationInst &AI); }; RegisterOpt X("instcombine", "Combine redundant instructions"); @@ -388,7 +389,8 @@ /// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use /// this predicate to simplify operations downstream. V and Mask are known to /// be the same type. -static bool MaskedValueIsZero(Value *V, ConstantIntegral *Mask) { +static bool MaskedValueIsZero(Value *V, ConstantIntegral *Mask, + unsigned Depth = 0) { // Note, we cannot consider 'undef' to be "IsZero" here. The problem is that // we cannot optimize based on the assumption that it is zero without changing // to to an explicit zero. If we don't change it to zero, other code could @@ -399,6 +401,8 @@ return true; if (ConstantIntegral *CI = dyn_cast(V)) return ConstantExpr::getAnd(CI, Mask)->isNullValue(); + + if (Depth == 6) return false; // Limit search depth. if (Instruction *I = dyn_cast(V)) { switch (I->getOpcode()) { @@ -407,21 +411,21 @@ if (ConstantIntegral *CI = dyn_cast(I->getOperand(1))) { ConstantIntegral *C1C2 = cast(ConstantExpr::getAnd(CI, Mask)); - if (MaskedValueIsZero(I->getOperand(0), C1C2)) + if (MaskedValueIsZero(I->getOperand(0), C1C2, Depth+1)) return true; } // If either the LHS or the RHS are MaskedValueIsZero, the result is zero. - return MaskedValueIsZero(I->getOperand(1), Mask) || - MaskedValueIsZero(I->getOperand(0), Mask); + return MaskedValueIsZero(I->getOperand(1), Mask, Depth+1) || + MaskedValueIsZero(I->getOperand(0), Mask, Depth+1); case Instruction::Or: case Instruction::Xor: // If the LHS and the RHS are MaskedValueIsZero, the result is also zero. - return MaskedValueIsZero(I->getOperand(1), Mask) && - MaskedValueIsZero(I->getOperand(0), Mask); + return MaskedValueIsZero(I->getOperand(1), Mask, Depth+1) && + MaskedValueIsZero(I->getOperand(0), Mask, Depth+1); case Instruction::Select: // If the T and F values are MaskedValueIsZero, the result is also zero. - return MaskedValueIsZero(I->getOperand(2), Mask) && - MaskedValueIsZero(I->getOperand(1), Mask); + return MaskedValueIsZero(I->getOperand(2), Mask, Depth+1) && + MaskedValueIsZero(I->getOperand(1), Mask, Depth+1); case Instruction::Cast: { const Type *SrcTy = I->getOperand(0)->getType(); if (SrcTy == Type::BoolTy) @@ -439,7 +443,7 @@ Constant *NewMask = ConstantExpr::getCast(Mask, I->getOperand(0)->getType()); return MaskedValueIsZero(I->getOperand(0), - cast(NewMask)); + cast(NewMask), Depth+1); } } break; @@ -448,7 +452,8 @@ // (shl X, C1) & C2 == 0 iff (X & C2 >>u C1) == 0 if (ConstantUInt *SA = dyn_cast(I->getOperand(1))) return MaskedValueIsZero(I->getOperand(0), - cast(ConstantExpr::getUShr(Mask, SA))); + cast(ConstantExpr::getUShr(Mask, SA)), + Depth+1); break; case Instruction::Shr: // (ushr X, C1) & C2 == 0 iff (-1 >> C1) & C2 == 0 @@ -705,7 +710,7 @@ // X + (signbit) --> X ^ signbit if (ConstantInt *CI = dyn_cast(RHSC)) { unsigned NumBits = CI->getType()->getPrimitiveSizeInBits(); - uint64_t Val = CI->getRawValue() & (1ULL << NumBits)-1; + uint64_t Val = CI->getRawValue() & (~0ULL >> (64- NumBits)); if (Val == (1ULL << (NumBits-1))) return BinaryOperator::createXor(LHS, RHS); } @@ -1235,13 +1240,32 @@ if (LHS->equalsInt(0)) return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); + if (I.getType()->isSigned()) { + // If the top bits of both operands are zero (i.e. we can prove they are + // unsigned inputs), turn this into a udiv. + ConstantIntegral *MaskV = ConstantSInt::getMinValue(I.getType()); + if (MaskedValueIsZero(Op1, MaskV) && MaskedValueIsZero(Op0, MaskV)) { + const Type *NTy = Op0->getType()->getUnsignedVersion(); + Instruction *LHS = new CastInst(Op0, NTy, Op0->getName()); + InsertNewInstBefore(LHS, I); + Value *RHS; + if (Constant *R = dyn_cast(Op1)) + RHS = ConstantExpr::getCast(R, NTy); + else + RHS = InsertNewInstBefore(new CastInst(Op1, NTy, Op1->getName()), I); + Instruction *Div = BinaryOperator::createDiv(LHS, RHS, I.getName()); + InsertNewInstBefore(Div, I); + return new CastInst(Div, I.getType()); + } + } + return 0; } Instruction *InstCombiner::visitRem(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); - if (I.getType()->isSigned()) + if (I.getType()->isSigned()) { if (Value *RHSNeg = dyn_castNegVal(Op1)) if (!isa(RHSNeg) || cast(RHSNeg)->getValue() > 0) { @@ -1250,6 +1274,24 @@ I.setOperand(1, RHSNeg); return &I; } + + // If the top bits of both operands are zero (i.e. we can prove they are + // unsigned inputs), turn this into a urem. + ConstantIntegral *MaskV = ConstantSInt::getMinValue(I.getType()); + if (MaskedValueIsZero(Op1, MaskV) && MaskedValueIsZero(Op0, MaskV)) { + const Type *NTy = Op0->getType()->getUnsignedVersion(); + Instruction *LHS = new CastInst(Op0, NTy, Op0->getName()); + InsertNewInstBefore(LHS, I); + Value *RHS; + if (Constant *R = dyn_cast(Op1)) + RHS = ConstantExpr::getCast(R, NTy); + else + RHS = InsertNewInstBefore(new CastInst(Op1, NTy, Op1->getName()), I); + Instruction *Rem = BinaryOperator::createRem(LHS, RHS, I.getName()); + InsertNewInstBefore(Rem, I); + return new CastInst(Rem, I.getType()); + } + } if (isa(Op0)) // undef % X -> 0 return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); @@ -1708,7 +1750,6 @@ return InsertNewInstBefore(New, I); } - Instruction *InstCombiner::visitAnd(BinaryOperator &I) { bool Changed = SimplifyCommutative(I); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); @@ -1724,6 +1765,15 @@ // and X, -1 == X if (AndRHS->isAllOnesValue()) return ReplaceInstUsesWith(I, Op0); + + // and (and X, c1), c2 -> and (x, c1&c2). Handle this case here, before + // calling MaskedValueIsZero, to avoid inefficient cases where we traipse + // through many levels of ands. + { + Value *X; ConstantInt *C1; + if (match(Op0, m_And(m_Value(X), m_ConstantInt(C1)))) + return BinaryOperator::createAnd(X, ConstantExpr::getAnd(C1, AndRHS)); + } if (MaskedValueIsZero(Op0, AndRHS)) // LHS & RHS == 0 return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); @@ -3762,6 +3812,149 @@ return CI; } +/// DecomposeSimpleLinearExpr - Analyze 'Val', seeing if it is a simple linear +/// expression. If so, decompose it, returning some value X, such that Val is +/// X*Scale+Offset. +/// +static Value *DecomposeSimpleLinearExpr(Value *Val, unsigned &Scale, + unsigned &Offset) { + assert(Val->getType() == Type::UIntTy && "Unexpected allocation size type!"); + if (ConstantUInt *CI = dyn_cast(Val)) { + Offset = CI->getValue(); + Scale = 1; + return ConstantUInt::get(Type::UIntTy, 0); + } else if (Instruction *I = dyn_cast(Val)) { + if (I->getNumOperands() == 2) { + if (ConstantUInt *CUI = dyn_cast(I->getOperand(1))) { + if (I->getOpcode() == Instruction::Shl) { + // This is a value scaled by '1 << the shift amt'. + Scale = 1U << CUI->getValue(); + Offset = 0; + return I->getOperand(0); + } else if (I->getOpcode() == Instruction::Mul) { + // This value is scaled by 'CUI'. + Scale = CUI->getValue(); + Offset = 0; + return I->getOperand(0); + } else if (I->getOpcode() == Instruction::Add) { + // We have X+C. Check to see if we really have (X*C2)+C1, where C1 is + // divisible by C2. + unsigned SubScale; + Value *SubVal = DecomposeSimpleLinearExpr(I->getOperand(0), SubScale, + Offset); + Offset += CUI->getValue(); + if (SubScale > 1 && (Offset % SubScale == 0)) { + Scale = SubScale; + return SubVal; + } + } + } + } + } + + // Otherwise, we can't look past this. + Scale = 1; + Offset = 0; + return Val; +} + + +/// PromoteCastOfAllocation - If we find a cast of an allocation instruction, +/// try to eliminate the cast by moving the type information into the alloc. +Instruction *InstCombiner::PromoteCastOfAllocation(CastInst &CI, + AllocationInst &AI) { + const PointerType *PTy = dyn_cast(CI.getType()); + if (!PTy) return 0; // Not casting the allocation to a pointer type. + + // Remove any uses of AI that are dead. + assert(!CI.use_empty() && "Dead instructions should be removed earlier!"); + std::vector DeadUsers; + for (Value::use_iterator UI = AI.use_begin(), E = AI.use_end(); UI != E; ) { + Instruction *User = cast(*UI++); + if (isInstructionTriviallyDead(User)) { + while (UI != E && *UI == User) + ++UI; // If this instruction uses AI more than once, don't break UI. + + // Add operands to the worklist. + AddUsesToWorkList(*User); + ++NumDeadInst; + DEBUG(std::cerr << "IC: DCE: " << *User); + + User->eraseFromParent(); + removeFromWorkList(User); + } + } + + // Get the type really allocated and the type casted to. + const Type *AllocElTy = AI.getAllocatedType(); + const Type *CastElTy = PTy->getElementType(); + if (!AllocElTy->isSized() || !CastElTy->isSized()) return 0; + + unsigned AllocElTyAlign = TD->getTypeSize(AllocElTy); + unsigned CastElTyAlign = TD->getTypeSize(CastElTy); + if (CastElTyAlign < AllocElTyAlign) return 0; + + // If the allocation has multiple uses, only promote it if we are strictly + // increasing the alignment of the resultant allocation. If we keep it the + // same, we open the door to infinite loops of various kinds. + if (!AI.hasOneUse() && CastElTyAlign == AllocElTyAlign) return 0; + + uint64_t AllocElTySize = TD->getTypeSize(AllocElTy); + uint64_t CastElTySize = TD->getTypeSize(CastElTy); + if (CastElTySize == 0 || AllocElTySize == 0) return 0; + + // See if we can satisfy the modulus by pulling a scale out of the array + // size argument. + unsigned ArraySizeScale, ArrayOffset; + Value *NumElements = // See if the array size is a decomposable linear expr. + DecomposeSimpleLinearExpr(AI.getOperand(0), ArraySizeScale, ArrayOffset); + + // If we can now satisfy the modulus, by using a non-1 scale, we really can + // do the xform. + if ((AllocElTySize*ArraySizeScale) % CastElTySize != 0 || + (AllocElTySize*ArrayOffset ) % CastElTySize != 0) return 0; + + unsigned Scale = (AllocElTySize*ArraySizeScale)/CastElTySize; + Value *Amt = 0; + if (Scale == 1) { + Amt = NumElements; + } else { + Amt = ConstantUInt::get(Type::UIntTy, Scale); + if (ConstantUInt *CI = dyn_cast(NumElements)) + Amt = ConstantExpr::getMul(CI, cast(Amt)); + else if (Scale != 1) { + Instruction *Tmp = BinaryOperator::createMul(Amt, NumElements, "tmp"); + Amt = InsertNewInstBefore(Tmp, AI); + } + } + + if (unsigned Offset = (AllocElTySize*ArrayOffset)/CastElTySize) { + Value *Off = ConstantUInt::get(Type::UIntTy, Offset); + Instruction *Tmp = BinaryOperator::createAdd(Amt, Off, "tmp"); + Amt = InsertNewInstBefore(Tmp, AI); + } + + std::string Name = AI.getName(); AI.setName(""); + AllocationInst *New; + if (isa(AI)) + New = new MallocInst(CastElTy, Amt, AI.getAlignment(), Name); + else + New = new AllocaInst(CastElTy, Amt, AI.getAlignment(), Name); + InsertNewInstBefore(New, AI); + + // If the allocation has multiple uses, insert a cast and change all things + // that used it to use the new cast. This will also hack on CI, but it will + // die soon. + if (!AI.hasOneUse()) { + AddUsesToWorkList(AI); + CastInst *NewCast = new CastInst(New, AI.getType(), "tmpcast"); + InsertNewInstBefore(NewCast, AI); + AI.replaceAllUsesWith(NewCast); + } + return ReplaceInstUsesWith(CI, New); +} + + // CastInst simplification // Instruction *InstCombiner::visitCastInst(CastInst &CI) { @@ -3840,30 +4033,8 @@ // size, rewrite the allocation instruction to allocate the "right" type. // if (AllocationInst *AI = dyn_cast(Src)) - if (AI->hasOneUse() && !AI->isArrayAllocation()) - if (const PointerType *PTy = dyn_cast(CI.getType())) { - // Get the type really allocated and the type casted to... - const Type *AllocElTy = AI->getAllocatedType(); - const Type *CastElTy = PTy->getElementType(); - if (AllocElTy->isSized() && CastElTy->isSized()) { - uint64_t AllocElTySize = TD->getTypeSize(AllocElTy); - uint64_t CastElTySize = TD->getTypeSize(CastElTy); - - // If the allocation is for an even multiple of the cast type size - if (CastElTySize && (AllocElTySize % CastElTySize == 0)) { - Value *Amt = ConstantUInt::get(Type::UIntTy, - AllocElTySize/CastElTySize); - std::string Name = AI->getName(); AI->setName(""); - AllocationInst *New; - if (isa(AI)) - New = new MallocInst(CastElTy, Amt, Name); - else - New = new AllocaInst(CastElTy, Amt, Name); - InsertNewInstBefore(New, *AI); - return ReplaceInstUsesWith(CI, New); - } - } - } + if (Instruction *V = PromoteCastOfAllocation(CI, *AI)) + return V; if (SelectInst *SI = dyn_cast(Src)) if (Instruction *NV = FoldOpIntoSelect(CI, SI, this)) @@ -4005,6 +4176,7 @@ break; } } + return 0; } @@ -5095,10 +5267,10 @@ // Create and insert the replacement instruction... if (isa(AI)) - New = new MallocInst(NewTy, 0, AI.getName()); + New = new MallocInst(NewTy, 0, AI.getAlignment(), AI.getName()); else { assert(isa(AI) && "Unknown type of allocation inst!"); - New = new AllocaInst(NewTy, 0, AI.getName()); + New = new AllocaInst(NewTy, 0, AI.getAlignment(), AI.getName()); } InsertNewInstBefore(New, AI); @@ -5597,7 +5769,6 @@ return 0; } - void InstCombiner::removeFromWorkList(Instruction *I) { WorkList.erase(std::remove(WorkList.begin(), WorkList.end(), I), WorkList.end()); @@ -5611,8 +5782,8 @@ static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock) { assert(I->hasOneUse() && "Invariants didn't hold!"); - // Cannot move control-flow-involving instructions. - if (isa(I) || isa(I) || isa(I)) return false; + // Cannot move control-flow-involving, volatile loads, vaarg, etc. + if (isa(I) || I->mayWriteToMemory()) return false; // Do not sink alloca instructions out of the entry block. if (isa(I) && I->getParent() == &DestBlock->getParent()->front()) @@ -5621,8 +5792,6 @@ // We can only sink load instructions if there is nothing between the load and // the end of block that could change the value. if (LoadInst *LI = dyn_cast(I)) { - if (LI->isVolatile()) return false; // Don't sink volatile loads. - for (BasicBlock::iterator Scan = LI, E = LI->getParent()->end(); Scan != E; ++Scan) if (Scan->mayWriteToMemory()) Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.68 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.68.2.1 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.68 Tue Oct 11 13:41:04 2005 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Wed Nov 16 12:32:53 2005 @@ -372,7 +372,8 @@ /// return true. Otherwise, return false. bool LoopStrengthReduce::AddUsersIfInteresting(Instruction *I, Loop *L, std::set &Processed) { - if (I->getType() == Type::VoidTy) return false; + if (!I->getType()->isInteger() && !isa(I->getType())) + return false; // Void and FP expressions cannot be reduced. if (!Processed.insert(I).second) return true; // Instruction already handled. Index: llvm/lib/Transforms/Scalar/LowerAllocations.cpp diff -u llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.54 llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.54.4.1 --- llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.54 Fri May 6 01:48:21 2005 +++ llvm/lib/Transforms/Scalar/LowerAllocations.cpp Wed Nov 16 12:32:53 2005 @@ -83,7 +83,7 @@ MallocFunc = M.getOrInsertFunction("malloc", FT); } if (FreeFunc == 0) - FreeFunc = M.getOrInsertFunction("free" , Type::VoidTy, SBPTy, 0); + FreeFunc = M.getOrInsertFunction("free" , Type::VoidTy, SBPTy, (Type *)0); return true; } Index: llvm/lib/Transforms/Scalar/LowerGC.cpp diff -u llvm/lib/Transforms/Scalar/LowerGC.cpp:1.8 llvm/lib/Transforms/Scalar/LowerGC.cpp:1.8.4.1 --- llvm/lib/Transforms/Scalar/LowerGC.cpp:1.8 Thu Apr 21 18:45:12 2005 +++ llvm/lib/Transforms/Scalar/LowerGC.cpp Wed Nov 16 12:32:53 2005 @@ -109,10 +109,11 @@ // If the program is using read/write barriers, find the implementations of // them from the GC runtime library. if (GCReadInt) // Make: sbyte* %llvm_gc_read(sbyte**) - GCRead = M.getOrInsertFunction("llvm_gc_read", VoidPtr, VoidPtr, VoidPtrPtr, 0); + GCRead = M.getOrInsertFunction("llvm_gc_read", VoidPtr, VoidPtr, VoidPtrPtr, + (Type *)0); if (GCWriteInt) // Make: void %llvm_gc_write(sbyte*, sbyte**) GCWrite = M.getOrInsertFunction("llvm_gc_write", Type::VoidTy, - VoidPtr, VoidPtr, VoidPtrPtr, 0); + VoidPtr, VoidPtr, VoidPtrPtr, (Type *)0); // If the program has GC roots, get or create the global root list. if (GCRootInt) { Index: llvm/lib/Transforms/Scalar/LowerInvoke.cpp diff -u llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.33 llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.33.2.1 --- llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.33 Fri Sep 30 22:57:14 2005 +++ llvm/lib/Transforms/Scalar/LowerInvoke.cpp Wed Nov 16 12:32:53 2005 @@ -67,6 +67,8 @@ GlobalVariable *JBListHead; Function *SetJmpFn, *LongJmpFn; public: + LowerInvoke(unsigned Size = 200, unsigned Align = 0) : JumpBufSize(Size), + JumpBufAlign(Align) {} bool doInitialization(Module &M); bool runOnFunction(Function &F); @@ -78,6 +80,9 @@ void rewriteExpensiveInvoke(InvokeInst *II, unsigned InvokeNo, AllocaInst *InvokeNum, SwitchInst *CatchSwitch); bool insertExpensiveEHSupport(Function &F); + + unsigned JumpBufSize; + unsigned JumpBufAlign; }; RegisterOpt @@ -87,7 +92,10 @@ const PassInfo *llvm::LowerInvokePassID = X.getPassInfo(); // Public Interface To the LowerInvoke pass. -FunctionPass *llvm::createLowerInvokePass() { return new LowerInvoke(); } +FunctionPass *llvm::createLowerInvokePass(unsigned JumpBufSize, + unsigned JumpBufAlign) { + return new LowerInvoke(JumpBufSize, JumpBufAlign); +} // doInitialization - Make sure that there is a prototype for abort in the // current module. @@ -95,13 +103,8 @@ const Type *VoidPtrTy = PointerType::get(Type::SByteTy); AbortMessage = 0; if (ExpensiveEHSupport) { - // Insert a type for the linked list of jump buffers. Unfortunately, we - // don't know the size of the target's setjmp buffer, so we make a guess. - // If this guess turns out to be too small, bad stuff could happen. - unsigned JmpBufSize = 200; // PPC has 192 words - assert(sizeof(jmp_buf) <= JmpBufSize*sizeof(void*) && - "LowerInvoke doesn't know about targets with jmp_buf size > 200 words!"); - const Type *JmpBufTy = ArrayType::get(VoidPtrTy, JmpBufSize); + // Insert a type for the linked list of jump buffers. + const Type *JmpBufTy = ArrayType::get(VoidPtrTy, JumpBufSize); { // The type is recursive, so use a type holder. std::vector Elements; @@ -124,14 +127,14 @@ Constant::getNullValue(PtrJBList), "llvm.sjljeh.jblist", &M); SetJmpFn = M.getOrInsertFunction("llvm.setjmp", Type::IntTy, - PointerType::get(JmpBufTy), NULL); + PointerType::get(JmpBufTy), (Type *)0); LongJmpFn = M.getOrInsertFunction("llvm.longjmp", Type::VoidTy, PointerType::get(JmpBufTy), - Type::IntTy, NULL); + Type::IntTy, (Type *)0); } // We need the 'write' and 'abort' functions for both models. - AbortFn = M.getOrInsertFunction("abort", Type::VoidTy, NULL); + AbortFn = M.getOrInsertFunction("abort", Type::VoidTy, (Type *)0); // Unfortunately, 'write' can end up being prototyped in several different // ways. If the user defines a three (or more) operand function named 'write' @@ -148,7 +151,7 @@ WriteFn = 0; } else { WriteFn = M.getOrInsertFunction("write", Type::VoidTy, Type::IntTy, - VoidPtrTy, Type::IntTy, NULL); + VoidPtrTy, Type::IntTy, (Type *)0); } return true; } @@ -441,7 +444,7 @@ // that needs to be restored on all exits from the function. This is an // alloca because the value needs to be live across invokes. AllocaInst *JmpBuf = - new AllocaInst(JBLinkTy, 0, "jblink", F.begin()->begin()); + new AllocaInst(JBLinkTy, 0, JumpBufAlign, "jblink", F.begin()->begin()); std::vector Idx; Idx.push_back(Constant::getNullValue(Type::IntTy)); Index: llvm/lib/Transforms/Scalar/Makefile diff -u llvm/lib/Transforms/Scalar/Makefile:1.4 llvm/lib/Transforms/Scalar/Makefile:1.4.6.1 --- llvm/lib/Transforms/Scalar/Makefile:1.4 Wed Oct 27 18:18:45 2004 +++ llvm/lib/Transforms/Scalar/Makefile Wed Nov 16 12:32:53 2005 @@ -6,6 +6,7 @@ # the University of Illinois Open Source License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## + LEVEL = ../../.. LIBRARYNAME = LLVMScalarOpts BUILD_ARCHIVE = 1 Index: llvm/lib/Transforms/Scalar/Reg2Mem.cpp diff -c /dev/null llvm/lib/Transforms/Scalar/Reg2Mem.cpp:1.3.2.2 *** /dev/null Wed Nov 16 12:33:05 2005 --- llvm/lib/Transforms/Scalar/Reg2Mem.cpp Wed Nov 16 12:32:53 2005 *************** *** 0 **** --- 1,81 ---- + //===- Reg2Mem.cpp - Convert registers to allocas -------------------------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by the LLVM research group and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file demotes all registers to memory references. It is intented to be + // the inverse of PromoteMemoryToRegister. By converting to loads, the only + // values live accross basic blocks are allocas and loads before phi nodes. + // It is intended that this should make CFG hacking much easier. + // To make later hacking easier, the entry block is split into two, such that + // all introduced allocas and nothing else are in the entry block. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Transforms/Scalar.h" + #include "llvm/Transforms/Utils/Local.h" + #include "llvm/Pass.h" + #include "llvm/Function.h" + #include "llvm/Module.h" + #include "llvm/BasicBlock.h" + #include "llvm/Instructions.h" + #include "llvm/ADT/Statistic.h" + + #include + + using namespace llvm; + + namespace { + Statistic<> NumDemoted("reg2mem", "Number of registers demoted"); + + struct RegToMem : public FunctionPass { + + bool valueEscapes(Instruction* i) { + BasicBlock* bb = i->getParent(); + for(Value::use_iterator ii = i->use_begin(), ie = i->use_end(); + ii != ie; ++ii) + if (cast(*ii)->getParent() != bb || + isa(*ii)) + return true; + return false; + } + + virtual bool runOnFunction(Function &F) { + if (!F.isExternal()) { + //give us a clean block + BasicBlock* bbold = &F.getEntryBlock(); + BasicBlock* bbnew = new BasicBlock("allocablock", &F, &F.getEntryBlock()); + new BranchInst(bbold, bbnew); + + //find the instructions + std::list worklist; + for (Function::iterator ibb = F.begin(), ibe = F.end(); + ibb != ibe; ++ibb) + for (BasicBlock::iterator iib = ibb->begin(), iie = ibb->end(); + iib != iie; ++iib) { + if(valueEscapes(iib)) + worklist.push_front(&*iib); + } + //demote escaped instructions + NumDemoted += worklist.size(); + for (std::list::iterator ilb = worklist.begin(), + ile = worklist.end(); ilb != ile; ++ilb) + DemoteRegToStack(**ilb, false); + return true; + } + return false; + } + }; + + RegisterOpt X("reg2mem", "Demote all values to stack slots"); + } + + // createDemoteRegisterToMemory - Provide an entry point to create this pass. + // + FunctionPass *llvm::createDemoteRegisterToMemoryPass() { + return new RegToMem(); + } Index: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp diff -u llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.31 llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.31.4.1 --- llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.31 Thu Apr 21 18:45:12 2005 +++ llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp Wed Nov 16 12:32:53 2005 @@ -159,7 +159,8 @@ if (const StructType *ST = dyn_cast(AI->getAllocatedType())) { ElementAllocas.reserve(ST->getNumContainedTypes()); for (unsigned i = 0, e = ST->getNumContainedTypes(); i != e; ++i) { - AllocaInst *NA = new AllocaInst(ST->getContainedType(i), 0, + AllocaInst *NA = new AllocaInst(ST->getContainedType(i), 0, + AI->getAlignment(), AI->getName() + "." + utostr(i), AI); ElementAllocas.push_back(NA); WorkList.push_back(NA); // Add to worklist for recursive processing @@ -169,7 +170,7 @@ ElementAllocas.reserve(AT->getNumElements()); const Type *ElTy = AT->getElementType(); for (unsigned i = 0, e = AT->getNumElements(); i != e; ++i) { - AllocaInst *NA = new AllocaInst(ElTy, 0, + AllocaInst *NA = new AllocaInst(ElTy, 0, AI->getAlignment(), AI->getName() + "." + utostr(i), AI); ElementAllocas.push_back(NA); WorkList.push_back(NA); // Add to worklist for recursive processing Index: llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp diff -u llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp:1.21 llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp:1.21.2.1 --- llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp:1.21 Mon Aug 8 14:11:57 2005 +++ llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp Wed Nov 16 12:32:53 2005 @@ -342,6 +342,7 @@ // constant, return the value returned by the tail call, or that are being // accumulator recursion variable eliminated. if (Ret->getNumOperands() != 0 && Ret->getReturnValue() != CI && + !isa(Ret->getReturnValue()) && AccumulatorRecursionEliminationInitVal == 0 && !getCommonReturnValue(Ret, CI)) return false; From bocchino at cs.uiuc.edu Wed Nov 16 12:33:22 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:22 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/test/Regression/Archive/ranlib_GNU.ll ranlib_SVR4.ll ranlib_xpg4.ll Message-ID: <200511161833.MAA21396@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Archive: ranlib_GNU.ll updated: 1.6 -> 1.6.6.1 ranlib_SVR4.ll updated: 1.6 -> 1.6.6.1 ranlib_xpg4.ll updated: 1.6 -> 1.6.6.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+3 -0) ranlib_GNU.ll | 1 + ranlib_SVR4.ll | 1 + ranlib_xpg4.ll | 1 + 3 files changed, 3 insertions(+) Index: llvm/test/Regression/Archive/ranlib_GNU.ll diff -u llvm/test/Regression/Archive/ranlib_GNU.ll:1.6 llvm/test/Regression/Archive/ranlib_GNU.ll:1.6.6.1 --- llvm/test/Regression/Archive/ranlib_GNU.ll:1.6 Sat Nov 27 00:44:10 2004 +++ llvm/test/Regression/Archive/ranlib_GNU.ll Wed Nov 16 12:33:11 2005 @@ -5,3 +5,4 @@ ;RUN: llvm-ranlib %t.GNU.a ;RUN: llvm-ar t %t.GNU.a > %t1 ;RUN: diff %t1 %p/GNU.toc + Index: llvm/test/Regression/Archive/ranlib_SVR4.ll diff -u llvm/test/Regression/Archive/ranlib_SVR4.ll:1.6 llvm/test/Regression/Archive/ranlib_SVR4.ll:1.6.6.1 --- llvm/test/Regression/Archive/ranlib_SVR4.ll:1.6 Sat Nov 27 00:44:10 2004 +++ llvm/test/Regression/Archive/ranlib_SVR4.ll Wed Nov 16 12:33:11 2005 @@ -5,3 +5,4 @@ ;RUN: llvm-ranlib %t.SVR4.a ;RUN: llvm-ar t %t.SVR4.a > %t1 ;RUN: diff %t1 %p/SVR4.toc + Index: llvm/test/Regression/Archive/ranlib_xpg4.ll diff -u llvm/test/Regression/Archive/ranlib_xpg4.ll:1.6 llvm/test/Regression/Archive/ranlib_xpg4.ll:1.6.6.1 --- llvm/test/Regression/Archive/ranlib_xpg4.ll:1.6 Sat Nov 27 00:44:10 2004 +++ llvm/test/Regression/Archive/ranlib_xpg4.ll Wed Nov 16 12:33:11 2005 @@ -5,3 +5,4 @@ ;RUN: llvm-ranlib %t.xpg4.a ;RUN: llvm-ar t %t.xpg4.a > %t1 ;RUN: diff %t1 %p/xpg4.toc + From bocchino at cs.uiuc.edu Wed Nov 16 12:33:25 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:25 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/test/Regression/CFrontend/2004-06-17-UnorderedCompares.c.tr 2005-02-20-AggregateSAVEEXPR.c 2005-10-18-VariableSizedElementCrash.c Message-ID: <200511161833.MAA21416@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2004-06-17-UnorderedCompares.c.tr updated: 1.4 -> 1.4.2.1 2005-02-20-AggregateSAVEEXPR.c updated: 1.2 -> 1.2.4.1 2005-10-18-VariableSizedElementCrash.c added (r1.1.4.2) --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+11 -2) 2004-06-17-UnorderedCompares.c.tr | 2 +- 2005-02-20-AggregateSAVEEXPR.c | 2 +- 2005-10-18-VariableSizedElementCrash.c | 9 +++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) Index: llvm/test/Regression/CFrontend/2004-06-17-UnorderedCompares.c.tr diff -u llvm/test/Regression/CFrontend/2004-06-17-UnorderedCompares.c.tr:1.4 llvm/test/Regression/CFrontend/2004-06-17-UnorderedCompares.c.tr:1.4.2.1 --- llvm/test/Regression/CFrontend/2004-06-17-UnorderedCompares.c.tr:1.4 Mon Sep 12 20:03:53 2005 +++ llvm/test/Regression/CFrontend/2004-06-17-UnorderedCompares.c.tr Wed Nov 16 12:33:13 2005 @@ -1,5 +1,5 @@ // RUN: %llvmgcc -xc -std=c99 %s -c -o - | llvm-dis | grep -v llvm.isunordered | not grep call -// XFAIL: sparcv9|ia64 +// XFAIL: sparc|ia64 #include Index: llvm/test/Regression/CFrontend/2005-02-20-AggregateSAVEEXPR.c diff -u llvm/test/Regression/CFrontend/2005-02-20-AggregateSAVEEXPR.c:1.2 llvm/test/Regression/CFrontend/2005-02-20-AggregateSAVEEXPR.c:1.2.4.1 --- llvm/test/Regression/CFrontend/2005-02-20-AggregateSAVEEXPR.c:1.2 Fri Apr 1 17:16:23 2005 +++ llvm/test/Regression/CFrontend/2005-02-20-AggregateSAVEEXPR.c Wed Nov 16 12:33:13 2005 @@ -6,7 +6,7 @@ // We could modify the test to use only GCC extensions, but I don't know if // that would change the nature of the test. // -// XFAIL: sparcv9 +// XFAIL: sparc #include Index: llvm/test/Regression/CFrontend/2005-10-18-VariableSizedElementCrash.c diff -c /dev/null llvm/test/Regression/CFrontend/2005-10-18-VariableSizedElementCrash.c:1.1.4.2 *** /dev/null Wed Nov 16 12:33:25 2005 --- llvm/test/Regression/CFrontend/2005-10-18-VariableSizedElementCrash.c Wed Nov 16 12:33:13 2005 *************** *** 0 **** --- 1,9 ---- + // RUN: %llvmgcc %s -S -o - + // XFAIL: * + int sub1(int i, char *pi) { + typedef int foo[i]; + struct bar {foo f1; int f2:3; int f3:4} *p = (struct bar *) pi; + xxx(p->f1); + return p->f3; + } + From bocchino at cs.uiuc.edu Wed Nov 16 12:33:26 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:26 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/test/Regression/CodeGen/Alpha/rpcc.ll Message-ID: <200511161833.MAA21423@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/Alpha: rpcc.ll added (r1.1.2.2) --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+10 -0) rpcc.ll | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/test/Regression/CodeGen/Alpha/rpcc.ll diff -c /dev/null llvm/test/Regression/CodeGen/Alpha/rpcc.ll:1.1.2.2 *** /dev/null Wed Nov 16 12:33:24 2005 --- llvm/test/Regression/CodeGen/Alpha/rpcc.ll Wed Nov 16 12:33:14 2005 *************** *** 0 **** --- 1,10 ---- + ; RUN: llvm-as < %s | llc -march=alpha | grep rpcc + + declare ulong %llvm.readcyclecounter() + + ulong %foo() { + entry: + %tmp.1 = call ulong %llvm.readcyclecounter () + ret ulong %tmp.1 + } + From bocchino at cs.uiuc.edu Wed Nov 16 12:33:29 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:29 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/test/Regression/CodeGen/Generic/2004-02-08-UnwindSupport.llx 2005-10-18-ZeroSizeStackObject.ll 2005-10-21-longlonggtu.ll ConstantExprLowering.llx isunord.ll Message-ID: <200511161833.MAA21447@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/Generic: 2004-02-08-UnwindSupport.llx added (r1.1.4.2) 2005-10-18-ZeroSizeStackObject.ll added (r1.1.4.2) 2005-10-21-longlonggtu.ll added (r1.1.4.2) ConstantExprLowering.llx updated: 1.2 -> 1.2.4.1 isunord.ll added (r1.3.2.2) --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+42 -1) 2004-02-08-UnwindSupport.llx | 13 +++++++++++++ 2005-10-18-ZeroSizeStackObject.ll | 6 ++++++ 2005-10-21-longlonggtu.ll | 12 ++++++++++++ ConstantExprLowering.llx | 2 +- isunord.ll | 10 ++++++++++ 5 files changed, 42 insertions(+), 1 deletion(-) Index: llvm/test/Regression/CodeGen/Generic/2004-02-08-UnwindSupport.llx diff -c /dev/null llvm/test/Regression/CodeGen/Generic/2004-02-08-UnwindSupport.llx:1.1.4.2 *** /dev/null Wed Nov 16 12:33:28 2005 --- llvm/test/Regression/CodeGen/Generic/2004-02-08-UnwindSupport.llx Wed Nov 16 12:33:17 2005 *************** *** 0 **** --- 1,13 ---- + ; RUN: llvm-as < %s | llc -enable-correct-eh-support + + int %test() { + unwind + } + + int %main() { + %X = invoke int %test() to label %cont except label %EH + cont: + ret int 1 + EH: + ret int 0 + } Index: llvm/test/Regression/CodeGen/Generic/2005-10-18-ZeroSizeStackObject.ll diff -c /dev/null llvm/test/Regression/CodeGen/Generic/2005-10-18-ZeroSizeStackObject.ll:1.1.4.2 *** /dev/null Wed Nov 16 12:33:29 2005 --- llvm/test/Regression/CodeGen/Generic/2005-10-18-ZeroSizeStackObject.ll Wed Nov 16 12:33:17 2005 *************** *** 0 **** --- 1,6 ---- + ; RUN: llvm-as < %s | llc + + void %test() { + %X = alloca {} + ret void + } Index: llvm/test/Regression/CodeGen/Generic/2005-10-21-longlonggtu.ll diff -c /dev/null llvm/test/Regression/CodeGen/Generic/2005-10-21-longlonggtu.ll:1.1.4.2 *** /dev/null Wed Nov 16 12:33:29 2005 --- llvm/test/Regression/CodeGen/Generic/2005-10-21-longlonggtu.ll Wed Nov 16 12:33:17 2005 *************** *** 0 **** --- 1,12 ---- + ; RUN: llvm-as < %s | llc + float %t(long %u) { + %u = cast long %u to ulong ; [#uses=1] + %tmp5 = add ulong %u, 9007199254740991 ; [#uses=1] + %tmp = setgt ulong %tmp5, 18014398509481982 ; [#uses=1] + br bool %tmp, label %T, label %F + T: + ret float 1.0 + F: + call float %t(long 0) + ret float 0.0 + } Index: llvm/test/Regression/CodeGen/Generic/ConstantExprLowering.llx diff -u llvm/test/Regression/CodeGen/Generic/ConstantExprLowering.llx:1.2 llvm/test/Regression/CodeGen/Generic/ConstantExprLowering.llx:1.2.4.1 --- llvm/test/Regression/CodeGen/Generic/ConstantExprLowering.llx:1.2 Fri Jan 7 15:37:13 2005 +++ llvm/test/Regression/CodeGen/Generic/ConstantExprLowering.llx Wed Nov 16 12:33:18 2005 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -lowerconstantexprs -disable-output +; RUN: llvm-as < %s | llc %.str_1 = internal constant [16 x sbyte] c"%d %d %d %d %d\0A\00" Index: llvm/test/Regression/CodeGen/Generic/isunord.ll diff -c /dev/null llvm/test/Regression/CodeGen/Generic/isunord.ll:1.3.2.2 *** /dev/null Wed Nov 16 12:33:29 2005 --- llvm/test/Regression/CodeGen/Generic/isunord.ll Wed Nov 16 12:33:18 2005 *************** *** 0 **** --- 1,10 ---- + ; RUN: llvm-as < %s | llc + ; XFAIL: ia64|sparcv8 + + + declare bool %llvm.isunordered(double, double) + + bool %test(double %X, double %Y) { + %tmp27 = call bool %llvm.isunordered( double %X, double %Y) + ret bool %tmp27 + } From bocchino at cs.uiuc.edu Wed Nov 16 12:33:31 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:31 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/test/Regression/CodeGen/IA64/2005-10-29-shladd.ll Message-ID: <200511161833.MAA21457@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/IA64: 2005-10-29-shladd.ll added (r1.1.4.2) --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+11 -0) 2005-10-29-shladd.ll | 11 +++++++++++ 1 files changed, 11 insertions(+) Index: llvm/test/Regression/CodeGen/IA64/2005-10-29-shladd.ll diff -c /dev/null llvm/test/Regression/CodeGen/IA64/2005-10-29-shladd.ll:1.1.4.2 *** /dev/null Wed Nov 16 12:33:29 2005 --- llvm/test/Regression/CodeGen/IA64/2005-10-29-shladd.ll Wed Nov 16 12:33:19 2005 *************** *** 0 **** --- 1,11 ---- + ; this should turn into shladd + ; RUN: llvm-as < %s | llc -march=ia64 | grep 'shladd' + + implementation ; Functions: + + long %bogglesmoggle(long %X, long %Y) { + %A = shl long %X, ubyte 3 + %B = add long %A, %Y + ret long %B + } + From bocchino at cs.uiuc.edu Wed Nov 16 12:33:33 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:33 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/test/Regression/CodeGen/X86/2004-02-08-UnwindSupport.llx Message-ID: <200511161833.MAA21481@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: 2004-02-08-UnwindSupport.llx (r1.2) removed --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+0 -0) 0 files changed From bocchino at cs.uiuc.edu Wed Nov 16 12:33:32 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:32 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/test/Regression/CodeGen/PowerPC/darwin-labels.ll fp_to_uint.ll mul-neg-power-2.ll reg-coalesce-simple.ll Message-ID: <200511161833.MAA21471@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/PowerPC: darwin-labels.ll added (r1.1.2.2) fp_to_uint.ll added (r1.1.4.2) mul-neg-power-2.ll added (r1.1.4.2) reg-coalesce-simple.ll added (r1.1.4.2) --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+38 -0) darwin-labels.ll | 8 ++++++++ fp_to_uint.ll | 9 +++++++++ mul-neg-power-2.ll | 9 +++++++++ reg-coalesce-simple.ll | 12 ++++++++++++ 4 files changed, 38 insertions(+) Index: llvm/test/Regression/CodeGen/PowerPC/darwin-labels.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/darwin-labels.ll:1.1.2.2 *** /dev/null Wed Nov 16 12:33:30 2005 --- llvm/test/Regression/CodeGen/PowerPC/darwin-labels.ll Wed Nov 16 12:33:20 2005 *************** *** 0 **** --- 1,8 ---- + ; RUN: llvm-as < %s | llc | grep 'foo bar":' + + target endian = big + target pointersize = 32 + target triple = "powerpc-apple-darwin8.2.0" + + "foo bar" = global int 4 + Index: llvm/test/Regression/CodeGen/PowerPC/fp_to_uint.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/fp_to_uint.ll:1.1.4.2 *** /dev/null Wed Nov 16 12:33:32 2005 --- llvm/test/Regression/CodeGen/PowerPC/fp_to_uint.ll Wed Nov 16 12:33:20 2005 *************** *** 0 **** --- 1,9 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 | grep fctiwz | wc -l | grep 1 + + implementation + + ushort %foo(float %a) { + entry: + %tmp.1 = cast float %a to ushort + ret ushort %tmp.1 + } Index: llvm/test/Regression/CodeGen/PowerPC/mul-neg-power-2.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/mul-neg-power-2.ll:1.1.4.2 *** /dev/null Wed Nov 16 12:33:32 2005 --- llvm/test/Regression/CodeGen/PowerPC/mul-neg-power-2.ll Wed Nov 16 12:33:20 2005 *************** *** 0 **** --- 1,9 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 && + ; RUN: llvm-as < %s | llc -march=ppc32 | not grep mul + + int %test1(int %a) { + %tmp.1 = mul int %a, -2 ; [#uses=1] + %tmp.2 = add int %tmp.1, 63 ; [#uses=1] + ret int %tmp.2 + } + Index: llvm/test/Regression/CodeGen/PowerPC/reg-coalesce-simple.ll diff -c /dev/null llvm/test/Regression/CodeGen/PowerPC/reg-coalesce-simple.ll:1.1.4.2 *** /dev/null Wed Nov 16 12:33:32 2005 --- llvm/test/Regression/CodeGen/PowerPC/reg-coalesce-simple.ll Wed Nov 16 12:33:20 2005 *************** *** 0 **** --- 1,12 ---- + ; RUN: llvm-as < %s | llc -march=ppc32 && + ; RUN: llvm-as < %s | llc -march=ppc32 | not grep or + + %struct.foo = type { int, int, [0 x ubyte] } + int %test(%struct.foo* %X) { + %tmp1 = getelementptr %struct.foo* %X, int 0, uint 2, int 100 + %tmp = load ubyte* %tmp1 ; [#uses=1] + %tmp2 = cast ubyte %tmp to int ; [#uses=1] + ret int %tmp2} + + + From bocchino at cs.uiuc.edu Wed Nov 16 12:33:35 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:35 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/test/Regression/ExecutionEngine/parallel.ll Message-ID: <200511161833.MAA21489@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/ExecutionEngine: parallel.ll updated: 1.1 -> 1.1.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+1 -1) parallel.ll | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/test/Regression/ExecutionEngine/parallel.ll diff -u llvm/test/Regression/ExecutionEngine/parallel.ll:1.1 llvm/test/Regression/ExecutionEngine/parallel.ll:1.1.2.1 --- llvm/test/Regression/ExecutionEngine/parallel.ll:1.1 Tue Jul 12 19:35:12 2005 +++ llvm/test/Regression/ExecutionEngine/parallel.ll Wed Nov 16 12:33:23 2005 @@ -1,3 +1,3 @@ ; This isn't really an assembly file. This test runs the ParallelJIT example ; program and ensures its output is sane. -; RUN: ParallelJIT | grep -q "Fib2 returned 267914296" +; RUN: ParallelJIT | grep "Fib2 returned 267914296" From bocchino at cs.uiuc.edu Wed Nov 16 12:33:37 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:37 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/test/Regression/Transforms/InstCombine/add.ll Message-ID: <200511161833.MAA21505@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: add.ll updated: 1.27 -> 1.27.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+7 -0) add.ll | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/test/Regression/Transforms/InstCombine/add.ll diff -u llvm/test/Regression/Transforms/InstCombine/add.ll:1.27 llvm/test/Regression/Transforms/InstCombine/add.ll:1.27.2.1 --- llvm/test/Regression/Transforms/InstCombine/add.ll:1.27 Sat Sep 17 23:22:59 2005 +++ llvm/test/Regression/Transforms/InstCombine/add.ll Wed Nov 16 12:33:26 2005 @@ -206,3 +206,10 @@ %tmp.10 = or uint %tmp.7, %tmp.9 ; [#uses=1] ret uint %tmp.10 } + +long %test30(long %x) { + %tmp.2 = xor long %x, -9223372036854775808 + ;; Add of sign bit -> xor of sign bit. + %tmp.4 = add long %tmp.2, -9223372036854775808 + ret long %tmp.4 +} From bocchino at cs.uiuc.edu Wed Nov 16 12:33:37 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:37 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/test/Regression/Transforms/BranchCombine/2004-06-01-Simple.ll dg.exp Message-ID: <200511161833.MAA21510@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/BranchCombine: 2004-06-01-Simple.ll (r1.1) removed dg.exp (r1.2) removed --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+0 -0) 0 files changed From bocchino at cs.uiuc.edu Wed Nov 16 12:33:39 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:39 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/test/Regression/Transforms/LoopStrengthReduce/nested-reduce.ll Message-ID: <200511161833.MAA21518@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LoopStrengthReduce: nested-reduce.ll added (r1.1.4.2) --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+57 -0) nested-reduce.ll | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 57 insertions(+) Index: llvm/test/Regression/Transforms/LoopStrengthReduce/nested-reduce.ll diff -c /dev/null llvm/test/Regression/Transforms/LoopStrengthReduce/nested-reduce.ll:1.1.4.2 *** /dev/null Wed Nov 16 12:33:37 2005 --- llvm/test/Regression/Transforms/LoopStrengthReduce/nested-reduce.ll Wed Nov 16 12:33:27 2005 *************** *** 0 **** --- 1,57 ---- + ; RUN: llvm-as < %s | opt -loop-reduce && + ; RUN: llvm-as < %s | opt -loop-reduce | llvm-dis | not grep mul + + ; Make sure we don't get a multiply by 6 in this loop. + + int %foo(int %A, int %B, int %C, int %D) { + entry: + %tmp.5 = setgt int %C, 0 ; [#uses=1] + %tmp.25 = and int %A, 1 ; [#uses=1] + br label %loopentry.1 + + loopentry.1: ; preds = %loopexit.1, %entry + %indvar20 = phi uint [ 0, %entry ], [ %indvar.next21, %loopexit.1 ] ; [#uses=2] + %k.1 = phi int [ 0, %entry ], [ %k.1.3, %loopexit.1 ] ; [#uses=2] + br bool %tmp.5, label %no_exit.1.preheader, label %loopexit.1 + + no_exit.1.preheader: ; preds = %loopentry.1 + %i.0.0 = cast uint %indvar20 to int ; [#uses=1] + %tmp.9 = mul int %i.0.0, 6 ; [#uses=1] + br label %no_exit.1.outer + + no_exit.1.outer: ; preds = %cond_true, %no_exit.1.preheader + %k.1.2.ph = phi int [ %k.1, %no_exit.1.preheader ], [ %k.09, %cond_true ] ; [#uses=2] + %j.1.2.ph = phi int [ 0, %no_exit.1.preheader ], [ %inc.1, %cond_true ] ; [#uses=1] + br label %no_exit.1 + + no_exit.1: ; preds = %cond_continue, %no_exit.1.outer + %indvar = phi uint [ 0, %no_exit.1.outer ], [ %indvar.next, %cond_continue ] ; [#uses=2] + %indvar = cast uint %indvar to int ; [#uses=1] + %j.1.2 = add int %indvar, %j.1.2.ph ; [#uses=2] + %tmp.11 = add int %j.1.2, %tmp.9 ; [#uses=1] + %tmp.12 = cast int %tmp.11 to ubyte ; [#uses=1] + %tmp.13 = shl int %D, ubyte %tmp.12 ; [#uses=2] + %tmp.15 = seteq int %tmp.13, %B ; [#uses=1] + %inc.1 = add int %j.1.2, 1 ; [#uses=3] + br bool %tmp.15, label %cond_true, label %cond_continue + + cond_true: ; preds = %no_exit.1 + %tmp.26 = and int %tmp.25, %tmp.13 ; [#uses=1] + %k.09 = add int %tmp.26, %k.1.2.ph ; [#uses=2] + %tmp.517 = setlt int %inc.1, %C ; [#uses=1] + br bool %tmp.517, label %no_exit.1.outer, label %loopexit.1 + + cond_continue: ; preds = %no_exit.1 + %tmp.519 = setlt int %inc.1, %C ; [#uses=1] + %indvar.next = add uint %indvar, 1 ; [#uses=1] + br bool %tmp.519, label %no_exit.1, label %loopexit.1 + + loopexit.1: ; preds = %cond_continue, %cond_true, %loopentry.1 + %k.1.3 = phi int [ %k.1, %loopentry.1 ], [ %k.09, %cond_true ], [ %k.1.2.ph, %cond_continue ] ; [#uses=2] + %indvar.next21 = add uint %indvar20, 1 ; [#uses=2] + %exitcond = seteq uint %indvar.next21, 4 ; [#uses=1] + br bool %exitcond, label %loopexit.0, label %loopentry.1 + + loopexit.0: ; preds = %loopexit.1 + ret int %k.1.3 + } From bocchino at cs.uiuc.edu Wed Nov 16 12:33:41 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:41 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/test/Regression/Transforms/TailCallElim/return-undef.ll Message-ID: <200511161833.MAA21532@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/TailCallElim: return-undef.ll added (r1.1.2.2) --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+8 -0) return-undef.ll | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm/test/Regression/Transforms/TailCallElim/return-undef.ll diff -c /dev/null llvm/test/Regression/Transforms/TailCallElim/return-undef.ll:1.1.2.2 *** /dev/null Wed Nov 16 12:33:40 2005 --- llvm/test/Regression/Transforms/TailCallElim/return-undef.ll Wed Nov 16 12:33:30 2005 *************** *** 0 **** --- 1,8 ---- + ; RUN: llvm-as < %s | opt -tailcallelim | llvm-dis | grep sub && + ; RUN: llvm-as < %s | opt -tailcallelim | llvm-dis | not grep call + + int %test(int %X) { + %Y = sub int %X, 1 + %Z = call int %test(int %Y) + ret int undef + } From bocchino at cs.uiuc.edu Wed Nov 16 12:33:43 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:43 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/tools/analyze/Makefile analyze.cpp Message-ID: <200511161833.MAA21548@zion.cs.uiuc.edu> Changes in directory llvm/tools/analyze: Makefile updated: 1.26 -> 1.26.4.1 analyze.cpp updated: 1.64 -> 1.64.4.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+3 -1) Makefile | 3 ++- analyze.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/tools/analyze/Makefile diff -u llvm/tools/analyze/Makefile:1.26 llvm/tools/analyze/Makefile:1.26.4.1 --- llvm/tools/analyze/Makefile:1.26 Fri Apr 22 12:14:14 2005 +++ llvm/tools/analyze/Makefile Wed Nov 16 12:33:31 2005 @@ -8,7 +8,8 @@ ##===----------------------------------------------------------------------===## LEVEL = ../.. TOOLNAME = analyze -USEDLIBS = LLVMAsmParser LLVMBCReader LLVMAnalysis LLVMipa LLVMDataStructure \ +USEDLIBS = LLVMAsmParser LLVMBCReader LLVMAnalysis.a LLVMipa.a \ + LLVMDataStructure \ LLVMScalarOpts.a LLVMTransforms.a LLVMTarget.a LLVMScalarOpts.a \ LLVMTransformUtils.a LLVMCore LLVMSupport.a LLVMbzip2 LLVMSystem.a Index: llvm/tools/analyze/analyze.cpp diff -u llvm/tools/analyze/analyze.cpp:1.64 llvm/tools/analyze/analyze.cpp:1.64.4.1 --- llvm/tools/analyze/analyze.cpp:1.64 Thu Apr 21 18:59:21 2005 +++ llvm/tools/analyze/analyze.cpp Wed Nov 16 12:33:31 2005 @@ -21,6 +21,7 @@ #include "llvm/Bytecode/Reader.h" #include "llvm/Assembly/Parser.h" #include "llvm/Analysis/Verifier.h" +#include "llvm/Analysis/LinkAllAnalyses.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/PassNameParser.h" #include "llvm/System/Signals.h" From bocchino at cs.uiuc.edu Wed Nov 16 12:33:42 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:42 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/test/Regression/Transforms/ProfilePaths/2002-05-22-CastCrash.ll dg.exp Message-ID: <200511161833.MAA21539@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/ProfilePaths: 2002-05-22-CastCrash.ll (r1.2) removed dg.exp (r1.2) removed --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+0 -0) 0 files changed From bocchino at cs.uiuc.edu Wed Nov 16 12:33:44 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:44 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/tools/bugpoint/Makefile Miscompilation.cpp bugpoint.cpp Message-ID: <200511161833.MAA21559@zion.cs.uiuc.edu> Changes in directory llvm/tools/bugpoint: Makefile updated: 1.12.4.1 -> 1.12.4.2 Miscompilation.cpp updated: 1.71 -> 1.71.2.1 bugpoint.cpp updated: 1.25 -> 1.25.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+7 -5) Makefile | 8 ++++---- Miscompilation.cpp | 2 +- bugpoint.cpp | 2 ++ 3 files changed, 7 insertions(+), 5 deletions(-) Index: llvm/tools/bugpoint/Makefile diff -u llvm/tools/bugpoint/Makefile:1.12.4.1 llvm/tools/bugpoint/Makefile:1.12.4.2 --- llvm/tools/bugpoint/Makefile:1.12.4.1 Tue Oct 18 14:21:59 2005 +++ llvm/tools/bugpoint/Makefile Wed Nov 16 12:33:33 2005 @@ -10,11 +10,11 @@ TOOLNAME = bugpoint -OPTLIBS = LLVMTransforms LLVMInstrumentation LLVMProfilePaths -ANALIBS = LLVMDataStructure LLVMipa LLVMTarget.a +OPTLIBS = LLVMTransforms.a LLVMInstrumentation.a +ANALIBS = LLVMDataStructure LLVMipa.a LLVMTarget.a -USEDLIBS = LLVMipo LLVMScalarOpts LLVMAnalysis $(OPTLIBS) $(ANALIBS) \ - LLVMTransformUtils \ +USEDLIBS = LLVMipo.a LLVMScalarOpts.a LLVMVectorOpts.a $(OPTLIBS) $(ANALIBS) LLVMAnalysis.a \ + LLVMTransformUtils.a \ LLVMAsmParser LLVMLinker.a LLVMBCReader LLVMBCWriter \ LLVMCore LLVMSupport.a LLVMbzip2 LLVMSystem.a #LLVMVectorOpts Index: llvm/tools/bugpoint/Miscompilation.cpp diff -u llvm/tools/bugpoint/Miscompilation.cpp:1.71 llvm/tools/bugpoint/Miscompilation.cpp:1.71.2.1 --- llvm/tools/bugpoint/Miscompilation.cpp:1.71 Tue Aug 2 18:25:56 2005 +++ llvm/tools/bugpoint/Miscompilation.cpp Wed Nov 16 12:33:33 2005 @@ -666,7 +666,7 @@ Function *resolverFunc = Safe->getOrInsertFunction("getPointerToNamedFunction", PointerType::get(Type::SByteTy), - PointerType::get(Type::SByteTy), 0); + PointerType::get(Type::SByteTy), (Type *)0); // Use the function we just added to get addresses of functions we need. for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) { Index: llvm/tools/bugpoint/bugpoint.cpp diff -u llvm/tools/bugpoint/bugpoint.cpp:1.25 llvm/tools/bugpoint/bugpoint.cpp:1.25.2.1 --- llvm/tools/bugpoint/bugpoint.cpp:1.25 Mon Aug 1 21:16:17 2005 +++ llvm/tools/bugpoint/bugpoint.cpp Wed Nov 16 12:33:33 2005 @@ -14,6 +14,8 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" +#include "llvm/Analysis/LinkAllAnalyses.h" +#include "llvm/Transforms/LinkAllPasses.h" #include "llvm/Support/PassNameParser.h" #include "llvm/Support/ToolRunner.h" #include "llvm/Support/CommandLine.h" From bocchino at cs.uiuc.edu Wed Nov 16 12:33:47 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:47 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/tools/gccld/GenerateCode.cpp Message-ID: <200511161833.MAA21579@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: GenerateCode.cpp updated: 1.54 -> 1.54.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+4 -1) GenerateCode.cpp | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/tools/gccld/GenerateCode.cpp diff -u llvm/tools/gccld/GenerateCode.cpp:1.54 llvm/tools/gccld/GenerateCode.cpp:1.54.2.1 --- llvm/tools/gccld/GenerateCode.cpp:1.54 Tue Oct 18 01:29:43 2005 +++ llvm/tools/gccld/GenerateCode.cpp Wed Nov 16 12:33:36 2005 @@ -423,7 +423,10 @@ // Add in the libraries to link. for (unsigned index = 0; index < Libraries.size(); index++) - if (Libraries[index] != "crtend") { + // HACK: If this is libg, discard it. This gets added by the compiler + // driver when doing: 'llvm-gcc main.c -Wl,-native -o a.out -g'. Note that + // this should really be fixed by changing the llvm-gcc compiler driver. + if (Libraries[index] != "crtend" && Libraries[index] != "g") { std::string Tmp = "-l"+Libraries[index]; StringsToDelete.push_back(strdup(Tmp.c_str())); args.push_back(StringsToDelete.back()); From bocchino at cs.uiuc.edu Wed Nov 16 12:33:46 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:46 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/tools/gccas/Makefile Message-ID: <200511161833.MAA21572@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccas: Makefile updated: 1.21 -> 1.21.4.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+2 -2) Makefile | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/tools/gccas/Makefile diff -u llvm/tools/gccas/Makefile:1.21 llvm/tools/gccas/Makefile:1.21.4.1 --- llvm/tools/gccas/Makefile:1.21 Sun Apr 24 12:43:37 2005 +++ llvm/tools/gccas/Makefile Wed Nov 16 12:33:34 2005 @@ -9,8 +9,8 @@ LEVEL = ../.. TOOLNAME = gccas -USEDLIBS = LLVMAsmParser LLVMBCWriter LLVMTransforms LLVMipo.a LLVMipa.a \ - LLVMScalarOpts LLVMAnalysis.a LLVMTarget.a LLVMTransformUtils \ +USEDLIBS = LLVMAsmParser LLVMBCWriter LLVMTransforms.a LLVMipo.a LLVMipa.a \ + LLVMScalarOpts.a LLVMAnalysis.a LLVMTarget.a LLVMTransformUtils.a \ LLVMCore LLVMSupport.a LLVMbzip2 LLVMSystem.a include $(LEVEL)/Makefile.common From bocchino at cs.uiuc.edu Wed Nov 16 12:33:49 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:49 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/tools/llc/Makefile llc.cpp Message-ID: <200511161833.MAA21594@zion.cs.uiuc.edu> Changes in directory llvm/tools/llc: Makefile updated: 1.73 -> 1.73.2.1 llc.cpp updated: 1.113 -> 1.113.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+11 -7) Makefile | 4 ++-- llc.cpp | 14 +++++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) Index: llvm/tools/llc/Makefile diff -u llvm/tools/llc/Makefile:1.73 llvm/tools/llc/Makefile:1.73.2.1 --- llvm/tools/llc/Makefile:1.73 Wed Jun 8 17:32:51 2005 +++ llvm/tools/llc/Makefile Wed Nov 16 12:33:37 2005 @@ -69,9 +69,9 @@ LLVMTarget.a \ LLVMipa.a \ LLVMTransforms.a \ - LLVMScalarOpts \ - LLVMAnalysis.a \ + LLVMScalarOpts.a \ LLVMTransformUtils.a \ + LLVMAnalysis.a \ LLVMBCReader \ LLVMBCWriter \ LLVMCore \ Index: llvm/tools/llc/llc.cpp diff -u llvm/tools/llc/llc.cpp:1.113 llvm/tools/llc/llc.cpp:1.113.2.1 --- llvm/tools/llc/llc.cpp:1.113 Fri Sep 2 14:27:43 2005 +++ llvm/tools/llc/llc.cpp Wed Nov 16 12:33:37 2005 @@ -45,20 +45,24 @@ static cl::opt Force("f", cl::desc("Overwrite output files")); +static cl::opt Fast("fast", + cl::desc("Generate code quickly, potentially sacrificing code quality")); + + static cl::opt MArch("march", cl::desc("Architecture to generate code for:")); static cl::opt MCPU("mcpu", - cl::desc("Target a specific cpu type (-mcpu=help for list of choices)"), + cl::desc("Target a specific cpu type (-mcpu=help for details)"), cl::value_desc("cpu-name"), cl::init("")); static cl::list MAttrs("mattr", cl::CommaSeparated, - cl::desc("Target specific attributes (-mattr=help for list of choices)"), - cl::value_desc("attr1,+attr2, ..., -attrN")); + cl::desc("Target specific attributes (-mattr=help for details)"), + cl::value_desc("a1,+a2,-a3,...")); cl::opt FileType("filetype", cl::init(TargetMachine::AssemblyFile), @@ -67,7 +71,7 @@ clEnumValN(TargetMachine::AssemblyFile, "asm", " Emit an assembly ('.s') file"), clEnumValN(TargetMachine::ObjectFile, "obj", - " Emit a native object ('.o') file"), + " Emit a native object ('.o') file [experimental]"), clEnumValN(TargetMachine::DynamicLibrary, "dynlib", " Emit a native dynamic library ('.so') file"), clEnumValEnd)); @@ -228,7 +232,7 @@ } // Ask the target to add backend passes as necessary. - if (Target.addPassesToEmitFile(Passes, *Out, FileType)) { + if (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) { std::cerr << argv[0] << ": target '" << Target.getName() << "' does not support generation of this file type!\n"; if (Out != &std::cout) delete Out; From bocchino at cs.uiuc.edu Wed Nov 16 12:33:50 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:50 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/tools/lli/lli.cpp Message-ID: <200511161833.MAA21604@zion.cs.uiuc.edu> Changes in directory llvm/tools/lli: lli.cpp updated: 1.49 -> 1.49.4.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+2 -1) lli.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/tools/lli/lli.cpp diff -u llvm/tools/lli/lli.cpp:1.49 llvm/tools/lli/lli.cpp:1.49.4.1 --- llvm/tools/lli/lli.cpp:1.49 Thu Apr 21 18:59:31 2005 +++ llvm/tools/lli/lli.cpp Wed Nov 16 12:33:38 2005 @@ -96,7 +96,8 @@ // If the program didn't explicitly call exit, call exit now, for the program. // This ensures that any atexit handlers get called correctly. Function *Exit = MP->getModule()->getOrInsertFunction("exit", Type::VoidTy, - Type::IntTy, 0); + Type::IntTy, + (Type *)0); std::vector Args; GenericValue ResultGV; From bocchino at cs.uiuc.edu Wed Nov 16 12:33:52 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:52 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/tools/llvmc/c cpp ll Message-ID: <200511161833.MAA21618@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvmc: c added (r1.1.4.2) cpp added (r1.3.4.2) ll added (r1.7.4.2) --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+134 -0) c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cpp | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ll | 12 ++++++++++++ 3 files changed, 134 insertions(+) Index: llvm/tools/llvmc/c diff -c /dev/null llvm/tools/llvmc/c:1.1.4.2 *** /dev/null Wed Nov 16 12:33:50 2005 --- llvm/tools/llvmc/c Wed Nov 16 12:33:40 2005 *************** *** 0 **** --- 1,61 ---- + # C configuration file for llvmc + + ########################################################## + # Language definitions + ########################################################## + lang.name=C + lang.opt1=-O1 + lang.opt2=-O2 + lang.opt3=-O3 + lang.opt4=-O3 + lang.opt5=-O3 + lang.libs=%llvmgccdir%/lib %llvmgccdir%/lib \ + %llvmgccdir%/lib/gcc/%llvmgccarch% + + ########################################################## + # Pre-processor definitions + ########################################################## + + # We use gcc as our pre-processor + preprocessor.command=gcc -E %in% -o %out% %incls% %defs% + preprocessor.required=true + + ########################################################## + # Translator definitions + ########################################################## + + # To compile C source, just use llvm-gcc's cc1 + translator.command=%llvmcc1% -quiet %in% -o %out% \ + %opt% %incls% %defs% %WOpts% %fOpts% %MOpts% %args% \ + -D_GNU_SOURCE + + # llvm-gcc does not pre-process + translator.preprocesses=false + + # The translator is required to run. + translator.required=true + + # Output of the translator is assembly + translator.output=assembly + + ########################################################## + # Optimizer definitions + ########################################################## + + # Use gccas to clean up the generated code + optimizer.command=%bindir%/gccas %in% -o %out% %args% + optimizer.required = true + + # gccas doesn't translate + optimizer.translates = false + + # gccas doesn't preprocess + optimizer.preprocesses=false + + # gccas produces bytecode + optimizer.output = bytecode + + ########################################################## + # Assembler definitions + ########################################################## + assembler.command=%bindir%/llc %in% -o %out% %target% %time% %stats% Index: llvm/tools/llvmc/cpp diff -c /dev/null llvm/tools/llvmc/cpp:1.3.4.2 *** /dev/null Wed Nov 16 12:33:51 2005 --- llvm/tools/llvmc/cpp Wed Nov 16 12:33:40 2005 *************** *** 0 **** --- 1,61 ---- + # C++ configuration file for llvmc + + ########################################################## + # Language definitions + ########################################################## + lang.name=C++ + lang.opt1=-O1 + lang.opt2=-O2 + lang.opt3=-O3 + lang.opt4=-O3 + lang.opt5=-O3 + lang.libs=%llvmgccdir%/lib %llvmgccdir%/lib \ + %llvmgccdir%/lib/gcc/%llvmgccarch% + + ########################################################## + # Pre-processor definitions + ########################################################## + + # We use g++ as our pre-processor + preprocessor.command=g++ -E %in% -o %out% %incls% %defs% + preprocessor.required=true + + ########################################################## + # Translator definitions + ########################################################## + + # To compile C++ source, just use llvm-g++'s cc1 + translator.command=%llvmcc1plus% -quiet %in% -o %out% \ + %opt% %incls% %defs% %WOpts% %fOpts% %MOpts% %args% \ + -D_GNU_SOURCE + + # llvm-g++ does not pre-process + translator.preprocesses=false + + # The translator is required to run. + translator.required=true + + # Output of translator is assembly + translator.output=assembly + + ########################################################## + # Optimizer definitions + ########################################################## + + # Use gccas to clean up the generated code + optimizer.command=%bindir%/gccas %in% -o %out% %args% + optimizer.required = true + + # gccas doesn't translate + optimizer.translates = false + + # gccas doesn't preprocess + optimizer.preprocesses=false + + # gccas produces bytecode + optimizer.output = bytecode + + ########################################################## + # Assembler definitions + ########################################################## + assembler.command=%bindir%/llc %in% -o %out% %target% %time% %stats% Index: llvm/tools/llvmc/ll diff -c /dev/null llvm/tools/llvmc/ll:1.7.4.2 *** /dev/null Wed Nov 16 12:33:51 2005 --- llvm/tools/llvmc/ll Wed Nov 16 12:33:40 2005 *************** *** 0 **** --- 1,12 ---- + # LLVM Assembly Config File For llvmc + version="1.0" + lang.name=LLVM Assembly + preprocessor.command= + preprocessor.required=false + translator.command=%bindir%/llvm-as %in% -o %out% + translator.optimizes=no + translator.preprocesses=true + translator.required=TRUE + optimizer.command=%bindir%/opt %in% -o %out% %opt% %args% + optimizer.translates=no + assembler.command=%bindir%/llc %in% -o %out% From bocchino at cs.uiuc.edu Wed Nov 16 12:33:52 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:52 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/tools/opt/Makefile Message-ID: <200511161833.MAA21625@zion.cs.uiuc.edu> Changes in directory llvm/tools/opt: Makefile updated: 1.49.4.1 -> 1.49.4.2 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+3 -3) Makefile | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/tools/opt/Makefile diff -u llvm/tools/opt/Makefile:1.49.4.1 llvm/tools/opt/Makefile:1.49.4.2 --- llvm/tools/opt/Makefile:1.49.4.1 Tue Oct 18 14:21:59 2005 +++ llvm/tools/opt/Makefile Wed Nov 16 12:33:41 2005 @@ -9,9 +9,9 @@ LEVEL = ../.. TOOLNAME = opt -USEDLIBS = LLVMBCReader LLVMBCWriter LLVMInstrumentation LLVMProfilePaths \ - LLVMScalarOpts LLVMVectorOpts LLVMipo LLVMipa LLVMDataStructure LLVMTransforms \ - LLVMTarget.a LLVMAnalysis LLVMTransformUtils LLVMCore LLVMSupport.a \ +USEDLIBS = LLVMBCReader LLVMBCWriter LLVMInstrumentation.a \ + LLVMScalarOpts.a LLVMVectorOpts.a LLVMipo.a LLVMipa.a LLVMDataStructure LLVMTransforms.a \ + LLVMTarget.a LLVMAnalysis.a LLVMTransformUtils.a LLVMCore LLVMSupport.a \ LLVMbzip2 LLVMSystem.a include $(LEVEL)/Makefile.common From bocchino at cs.uiuc.edu Wed Nov 16 12:33:55 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:55 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/utils/NightlyTest.gnuplot NightlyTest.pl NightlyTestTemplate.html Message-ID: <200511161833.MAA21642@zion.cs.uiuc.edu> Changes in directory llvm/utils: NightlyTest.gnuplot updated: 1.13 -> 1.13.2.1 NightlyTest.pl updated: 1.97 -> 1.97.2.1 NightlyTestTemplate.html updated: 1.41 -> 1.41.4.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+24 -60) NightlyTest.gnuplot | 47 ----------------------------------------------- NightlyTest.pl | 29 +++++++++++++++++++++++------ NightlyTestTemplate.html | 8 +------- 3 files changed, 24 insertions(+), 60 deletions(-) Index: llvm/utils/NightlyTest.gnuplot diff -u llvm/utils/NightlyTest.gnuplot:1.13 llvm/utils/NightlyTest.gnuplot:1.13.2.1 --- llvm/utils/NightlyTest.gnuplot:1.13 Sun Oct 2 16:51:38 2005 +++ llvm/utils/NightlyTest.gnuplot Wed Nov 16 12:33:43 2005 @@ -8,15 +8,6 @@ set timefmt "%Y-%m-%d-%H:%M:%S:" set format x "%b %d, %Y" -## Various labels for the graph -set label "Reoptimizer\n checkins" at "2003-02-18:", 114000 -set label "Modulo Sched\n checkin" at "2003-03-28:", 119500 -set label "Reoptimizer\n checkins" at "2003-06-01:", 134000 -set label "'dummy'\nfunction" at "2003-07-20:", 150000 -set label "Reoptimizer\n removal" at "2003-08-10:", 132000 -set label "llvm-db\ncheckin" at "2004-01-04:", 145000 -set label "llvm/projects" at "2004-01-04:", 151000 - set size .75,.75 set xtics rotate set xlabel 0,-1 @@ -185,44 +176,6 @@ with lines -##------- Machine code size ---- - -set size .75,.75 -set xtics rotate -set xlabel 0,-1 -set output "running_Olden_machcode.png" -set ylabel "Program machine code size (bytes)" -plot "running_Olden_machcode.txt" u 1:2 t '' with lines, \ - "running_Olden_machcode.txt" u 1:2 t "bh" with lines, \ - "running_Olden_machcode.txt" u 1:3 t "em3d" with lines, \ - "running_Olden_machcode.txt" u 1:4 t "mst" with lines, \ - "running_Olden_machcode.txt" u 1:5 t "power" with lines, \ - "running_Olden_machcode.txt" u 1:6 t "tsp" with lines, \ - "running_Olden_machcode.txt" u 1:7 t "bisort" with lines, \ - "running_Olden_machcode.txt" u 1:8 t "health" with lines, \ - "running_Olden_machcode.txt" u 1:9 t "perimeter" with lines, \ - "running_Olden_machcode.txt" u 1:10 t "treeadd" with lines, \ - "running_Olden_machcode.txt" u 1:11 t "voronoi" \ - with lines - -set size 1.5,1.5 -set xtics norotate -set xlabel 0,0 -set output "running_Olden_machcode_large.png" -plot "running_Olden_machcode.txt" u 1:2 t '' with lines, \ - "running_Olden_machcode.txt" u 1:2 t "bh" with lines, \ - "running_Olden_machcode.txt" u 1:3 t "em3d" with lines, \ - "running_Olden_machcode.txt" u 1:4 t "mst" with lines, \ - "running_Olden_machcode.txt" u 1:5 t "power" with lines, \ - "running_Olden_machcode.txt" u 1:6 t "tsp" with lines, \ - "running_Olden_machcode.txt" u 1:7 t "bisort" with lines, \ - "running_Olden_machcode.txt" u 1:8 t "health" with lines, \ - "running_Olden_machcode.txt" u 1:9 t "perimeter" with lines, \ - "running_Olden_machcode.txt" u 1:10 t "treeadd" with lines, \ - "running_Olden_machcode.txt" u 1:11 t "voronoi" \ - with lines - - ##------- Bytecode size ---- set size .75,.75 Index: llvm/utils/NightlyTest.pl diff -u llvm/utils/NightlyTest.pl:1.97 llvm/utils/NightlyTest.pl:1.97.2.1 --- llvm/utils/NightlyTest.pl:1.97 Mon Jun 6 14:17:05 2005 +++ llvm/utils/NightlyTest.pl Wed Nov 16 12:33:43 2005 @@ -38,6 +38,12 @@ # testing release branches) # -target Specify the target triplet # +# ---------------- Options to configure llvm-test ---------------------------- +# -spec2000path Path to the benchspec directory in the SPEC 2000 distro +# -spec95path Path to the benchspec directory in the SPEC 95 distro. +# -povraypath Path to the povray sources +# -namdpath Path to the namd sources +# # CVSROOT is the CVS repository from which the tree will be checked out, # specified either in the full :method:user at host:/dir syntax, or # just /dir if using a local repo. @@ -86,6 +92,8 @@ my $NICE = ""; my $NODEJAGNU = 0; +my $LLVMTESTCONFIGARGS = ""; + sub ReadFile { if (open (FILE, $_[0])) { undef $/; @@ -298,7 +306,18 @@ } if (/^-noexternals$/) { $NOEXTERNALS = 1; next; } if (/^-nodejagnu$/) { $NODEJAGNU = 1; next; } - + if (/^-spec2000path$/) { + $LLVMTESTCONFIGARGS .= " --enable-spec2000=$ARGV[0]"; shift; next; + } + if (/^-spec95path$/) { + $LLVMTESTCONFIGARGS .= " --enable-spec95=$ARGV[0]"; shift; next; + } + if (/^-povraypath$/) { + $LLVMTESTCONFIGARGS .= " --enable-povray=$ARGV[0]"; shift; next; + } + if (/^-namdpath$/) { + $LLVMTESTCONFIGARGS .= " --enable-namd=$ARGV[0]"; shift; next; + } print "Unknown option: $_ : ignoring!\n"; } @@ -410,7 +429,8 @@ # if (!$NOCHECKOUT) { if ( $VERBOSE ) { print "CONFIGURE STAGE\n"; } - system "(time -p $NICE ./configure $CONFIGUREARGS --enable-spec --with-objroot=.) > $BuildLog 2>&1"; + my $EXTRAFLAGS = "--enable-spec --with-objroot=.$LLVMTESTCONFIGARGS"; + system "(time -p $NICE ./configure $CONFIGUREARGS $EXTRAFLAGS) > $BuildLog 2>&1"; if ( $VERBOSE ) { print "BUILD STAGE\n"; } # Build the entire tree, capturing the output into $BuildLog @@ -720,7 +740,6 @@ my $rJITTime = GetRegex 'TEST-RESULT-jit-time: program\s*([.0-9m]+)', $Rec; my $rOptTime = GetRegex "TEST-RESULT-compile: .*$WallTimeRE", $Rec; my $rBytecodeSize = GetRegex 'TEST-RESULT-compile: *([0-9]+)', $Rec; - my $rMachCodeSize = GetRegex 'TEST-RESULT-jit-machcode: *([0-9]+).*bytes of machine code', $Rec; $NATTime .= " " . FormatTime($rNATTime); $CBETime .= " " . FormatTime($rCBETime); @@ -728,7 +747,6 @@ $JITTime .= " " . FormatTime($rJITTime); $OptTime .= " $rOptTime"; $BytecodeSize .= " $rBytecodeSize"; - $MachCodeSize .= " $rMachCodeSize"; } # Now that we have all of the numbers we want, add them to the running totals @@ -739,7 +757,6 @@ AddRecord($JITTime, "running_Olden_jit_time.txt"); AddRecord($OptTime, "running_Olden_opt_time.txt"); AddRecord($BytecodeSize, "running_Olden_bytecode.txt"); - AddRecord($MachCodeSize, "running_Olden_machcode.txt"); system "gzip -f $OldenTestsLog"; } @@ -765,7 +782,7 @@ # Make sure we don't get errors running the nightly tester the first time # because of files that don't exist. Touch ('running_build_time.txt', 'running_Olden_llc_time.txt', - 'running_loc.txt', 'running_Olden_machcode.txt', + 'running_loc.txt', 'running_Olden_bytecode.txt', 'running_Olden_nat_time.txt', 'running_Olden_cbe_time.txt', 'running_Olden_opt_time.txt', 'running_Olden_jit_time.txt'); Index: llvm/utils/NightlyTestTemplate.html diff -u llvm/utils/NightlyTestTemplate.html:1.41 llvm/utils/NightlyTestTemplate.html:1.41.4.1 --- llvm/utils/NightlyTestTemplate.html:1.41 Sun Feb 13 10:08:30 2005 +++ llvm/utils/NightlyTestTemplate.html Wed Nov 16 12:33:43 2005 @@ -142,15 +142,9 @@ Size of LLVM bytecode files -
    -Size of native machine code for each program (generated by the JIT) - - -
    Time to run the LLVM optimizer on each program - - +

    Program Execution Measurements:

    From bocchino at cs.uiuc.edu Wed Nov 16 12:33:58 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:58 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/win32/dobison.cmd doflex.cmd Message-ID: <200511161833.MAA21689@zion.cs.uiuc.edu> Changes in directory llvm/win32: dobison.cmd added (r1.2.4.2) doflex.cmd added (r1.2.4.2) --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+42 -0) dobison.cmd | 22 ++++++++++++++++++++++ doflex.cmd | 20 ++++++++++++++++++++ 2 files changed, 42 insertions(+) Index: llvm/win32/dobison.cmd diff -c /dev/null llvm/win32/dobison.cmd:1.2.4.2 *** /dev/null Wed Nov 16 12:33:56 2005 --- llvm/win32/dobison.cmd Wed Nov 16 12:33:46 2005 *************** *** 0 **** --- 1,22 ---- + @echo off + rem dobison.cmd prefix mode target source + rem prefix - passed to bison as -p + rem mode - either debug or release + rem target - generated parser file name without extension + rem source - input to bison + + if "%2"=="debug" (set flags=-tvdo) else (set flags=-vdo) + + rem Test for presence of bison. + bison --help >NUL + if errorlevel 1 goto nobison + + rem Run bison. + bison -p%1 %flags%%3.cpp %4 && move %3.hpp %3.h + exit + + :nobison + echo Bison not found. Using pre-generated files. + copy %~pn4.cpp %3.cpp + copy %~pn4.h %3.h + exit Index: llvm/win32/doflex.cmd diff -c /dev/null llvm/win32/doflex.cmd:1.2.4.2 *** /dev/null Wed Nov 16 12:33:58 2005 --- llvm/win32/doflex.cmd Wed Nov 16 12:33:46 2005 *************** *** 0 **** --- 1,20 ---- + @echo off + rem doflex.cmd prefix mode target source + rem mode - either debug or release + rem target - generated parser file name without extension + rem source - input to bison + + if "%1"=="debug" (set flags=-t) else (set flags=-t) + + rem Test for presence of flex. + flex --help >NUL + if errorlevel 1 goto noflex + + rem Run flex. + flex %flags% >%2.cpp %3 + exit + + :noflex + echo Flex not found. Using pre-generated files. + copy %~pn3.cpp %2.cpp + exit From bocchino at cs.uiuc.edu Wed Nov 16 12:33:59 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:59 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/win32/Analysis/Analysis.vcproj Message-ID: <200511161833.MAA21697@zion.cs.uiuc.edu> Changes in directory llvm/win32/Analysis: Analysis.vcproj updated: 1.12 -> 1.12.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+4 -13) Analysis.vcproj | 17 ++++------------- 1 files changed, 4 insertions(+), 13 deletions(-) Index: llvm/win32/Analysis/Analysis.vcproj diff -u llvm/win32/Analysis/Analysis.vcproj:1.12 llvm/win32/Analysis/Analysis.vcproj:1.12.2.1 --- llvm/win32/Analysis/Analysis.vcproj:1.12 Sat Jul 30 13:22:27 2005 +++ llvm/win32/Analysis/Analysis.vcproj Wed Nov 16 12:33:48 2005 @@ -125,7 +125,7 @@ RelativePath="..\..\lib\Analysis\CFGPrinter.cpp"> + RelativePath="..\..\lib\Analysis\ConstantFolding.cpp"> @@ -179,17 +179,11 @@ RelativePath="..\..\lib\Analysis\Ipa\CallGraphSCCPass.cpp"> - - - - - - + RelativePath="..\..\include\llvm\Analysis\ConstantFolding.h"> + RelativePath="..\..\include\llvm\Analysis\ConstantsScanner.h"> + RelativePath="..\..\include\llvm\Analysis\Dominators.h"> From bocchino at cs.uiuc.edu Wed Nov 16 12:34:00 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:34:00 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/win32/AsmParser/.cvsignore AsmParser.vcproj Message-ID: <200511161834.MAA21707@zion.cs.uiuc.edu> Changes in directory llvm/win32/AsmParser: .cvsignore added (r1.1.4.2) AsmParser.vcproj updated: 1.5 -> 1.5.4.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+17 -17) .cvsignore | 4 ++++ AsmParser.vcproj | 30 +++++++++++++----------------- 2 files changed, 17 insertions(+), 17 deletions(-) Index: llvm/win32/AsmParser/.cvsignore diff -c /dev/null llvm/win32/AsmParser/.cvsignore:1.1.4.2 *** /dev/null Wed Nov 16 12:33:59 2005 --- llvm/win32/AsmParser/.cvsignore Wed Nov 16 12:33:49 2005 *************** *** 0 **** --- 1,4 ---- + Lexer.cpp + llvmAsmParser.cpp + llvmAsmParser.h + llvmAsmParser.output Index: llvm/win32/AsmParser/AsmParser.vcproj diff -u llvm/win32/AsmParser/AsmParser.vcproj:1.5 llvm/win32/AsmParser/AsmParser.vcproj:1.5.4.1 --- llvm/win32/AsmParser/AsmParser.vcproj:1.5 Wed Feb 2 00:33:11 2005 +++ llvm/win32/AsmParser/AsmParser.vcproj Wed Nov 16 12:33:49 2005 @@ -20,7 +20,7 @@ + CommandLine="..\doflex.cmd debug $(InputName) $(InputPath)" + Outputs="$(InputName).cpp"/> + CommandLine="..\doflex.cmd release $(InputName) $(InputPath)" + Outputs="$(InputName).cpp"/> + CommandLine="..\dobison.cmd llvmAsm debug $(InputName) $(InputPath)" + Outputs="$(InputName).cpp;$(InputName).h;$(InputName).output"/> + CommandLine="..\dobison.cmd llvmAsm release $(InputName) $(InputPath)" + Outputs="$(InputName).cpp;$(InputName).h;$(InputName).output"/> + RelativePath="Lexer.cpp"> + RelativePath="llvmAsmParser.cpp"> + RelativePath="llvmAsmParser.h"> From bocchino at cs.uiuc.edu Wed Nov 16 12:33:56 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:33:56 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/utils/TableGen/CodeEmitterGen.cpp CodeGenTarget.cpp DAGISelEmitter.cpp DAGISelEmitter.h InstrInfoEmitter.cpp InstrInfoEmitter.h InstrSelectorEmitter.cpp InstrSelectorEmitter.h Record.cpp Record.h RegisterInfoEmitter.cpp SubtargetEmitter.cpp SubtargetEmitter.h TableGen.cpp Message-ID: <200511161833.MAA21674@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeEmitterGen.cpp updated: 1.41 -> 1.41.2.1 CodeGenTarget.cpp updated: 1.40 -> 1.40.2.1 DAGISelEmitter.cpp updated: 1.59 -> 1.59.2.1 DAGISelEmitter.h updated: 1.33 -> 1.33.2.1 InstrInfoEmitter.cpp updated: 1.28 -> 1.28.2.1 InstrInfoEmitter.h updated: 1.10 -> 1.10.2.1 InstrSelectorEmitter.cpp (r1.45) removed InstrSelectorEmitter.h (r1.27) removed Record.cpp updated: 1.45 -> 1.45.2.1 Record.h updated: 1.52 -> 1.52.2.1 RegisterInfoEmitter.cpp updated: 1.36 -> 1.36.2.1 SubtargetEmitter.cpp added (r1.14.2.2) SubtargetEmitter.h added (r1.7.2.2) TableGen.cpp updated: 1.39 -> 1.39.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+894 -122) CodeEmitterGen.cpp | 3 CodeGenTarget.cpp | 28 -- DAGISelEmitter.cpp | 242 ++++++++++++++++++---- DAGISelEmitter.h | 17 + InstrInfoEmitter.cpp | 80 ++++--- InstrInfoEmitter.h | 9 Record.cpp | 19 + Record.h | 6 RegisterInfoEmitter.cpp | 19 - SubtargetEmitter.cpp | 516 ++++++++++++++++++++++++++++++++++++++++++++++++ SubtargetEmitter.h | 62 +++++ TableGen.cpp | 15 - 12 files changed, 894 insertions(+), 122 deletions(-) Index: llvm/utils/TableGen/CodeEmitterGen.cpp diff -u llvm/utils/TableGen/CodeEmitterGen.cpp:1.41 llvm/utils/TableGen/CodeEmitterGen.cpp:1.41.2.1 --- llvm/utils/TableGen/CodeEmitterGen.cpp:1.41 Thu Aug 18 20:04:33 2005 +++ llvm/utils/TableGen/CodeEmitterGen.cpp Wed Nov 16 12:33:45 2005 @@ -76,7 +76,6 @@ std::vector Insts = Records.getAllDerivedDefinitions("Instruction"); EmitSourceFileHeader("Machine Code Emitter", o); - o << "namespace llvm {\n\n"; std::string Namespace = Insts[0]->getValueAsString("Namespace") + "::"; // Emit function declaration @@ -255,6 +254,4 @@ << " }\n" << " return Value;\n" << "}\n\n"; - - o << "} // End llvm namespace \n"; } Index: llvm/utils/TableGen/CodeGenTarget.cpp diff -u llvm/utils/TableGen/CodeGenTarget.cpp:1.40 llvm/utils/TableGen/CodeGenTarget.cpp:1.40.2.1 --- llvm/utils/TableGen/CodeGenTarget.cpp:1.40 Thu Oct 13 22:54:49 2005 +++ llvm/utils/TableGen/CodeGenTarget.cpp Wed Nov 16 12:33:45 2005 @@ -84,15 +84,8 @@ throw std::string("ERROR: Multiple subclasses of Target defined!"); TargetRec = Targets[0]; - // Read in all of the CalleeSavedRegisters... - ListInit *LI = TargetRec->getValueAsListInit("CalleeSavedRegisters"); - for (unsigned i = 0, e = LI->getSize(); i != e; ++i) - if (DefInit *DI = dynamic_cast(LI->getElement(i))) - CalleeSavedRegisters.push_back(DI->getDef()); - else - throw "Target: " + TargetRec->getName() + - " expected register definition in CalleeSavedRegisters list!"; - + // Read in all of the CalleeSavedRegisters. + CalleeSavedRegisters =TargetRec->getValueAsListOfDefs("CalleeSavedRegisters"); PointerType = getValueType(TargetRec->getValueAsDef("PointerType")); } @@ -108,12 +101,10 @@ /// getAsmWriter - Return the AssemblyWriter definition for this target. /// Record *CodeGenTarget::getAsmWriter() const { - ListInit *LI = TargetRec->getValueAsListInit("AssemblyWriters"); - if (AsmWriterNum >= LI->getSize()) + std::vector LI = TargetRec->getValueAsListOfDefs("AssemblyWriters"); + if (AsmWriterNum >= LI.size()) throw "Target does not have an AsmWriter #" + utostr(AsmWriterNum) + "!"; - DefInit *DI = dynamic_cast(LI->getElement(AsmWriterNum)); - if (!DI) throw std::string("AssemblyWriter list should be a list of defs!"); - return DI->getDef(); + return LI[AsmWriterNum]; } void CodeGenTarget::ReadRegisters() const { @@ -159,12 +150,9 @@ MethodBodies = R->getValueAsCode("MethodBodies"); MethodProtos = R->getValueAsCode("MethodProtos"); - ListInit *RegList = R->getValueAsListInit("MemberList"); - for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { - DefInit *RegDef = dynamic_cast(RegList->getElement(i)); - if (!RegDef) throw "Register class member is not a record!"; - Record *Reg = RegDef->getDef(); - + std::vector RegList = R->getValueAsListOfDefs("MemberList"); + for (unsigned i = 0, e = RegList.size(); i != e; ++i) { + Record *Reg = RegList[i]; if (!Reg->isSubClassOf("Register")) throw "Register Class member '" + Reg->getName() + "' does not derive from the Register class!"; Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.59 llvm/utils/TableGen/DAGISelEmitter.cpp:1.59.2.1 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.59 Mon Oct 17 23:41:01 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Wed Nov 16 12:33:45 2005 @@ -228,16 +228,14 @@ // Parse the properties. Properties = 0; - ListInit *LI = R->getValueAsListInit("Properties"); - for (unsigned i = 0, e = LI->getSize(); i != e; ++i) { - DefInit *DI = dynamic_cast(LI->getElement(i)); - assert(DI && "Properties list must be list of defs!"); - if (DI->getDef()->getName() == "SDNPCommutative") { + std::vector PropList = R->getValueAsListOfDefs("Properties"); + for (unsigned i = 0, e = PropList.size(); i != e; ++i) { + if (PropList[i]->getName() == "SDNPCommutative") { Properties |= 1 << SDNPCommutative; - } else if (DI->getDef()->getName() == "SDNPAssociative") { + } else if (PropList[i]->getName() == "SDNPAssociative") { Properties |= 1 << SDNPAssociative; } else { - std::cerr << "Unknown SD Node property '" << DI->getDef()->getName() + std::cerr << "Unknown SD Node property '" << PropList[i]->getName() << "' on node '" << R->getName() << "'!\n"; exit(1); } @@ -245,14 +243,9 @@ // Parse the type constraints. - ListInit *Constraints = TypeProfile->getValueAsListInit("Constraints"); - for (unsigned i = 0, e = Constraints->getSize(); i != e; ++i) { - assert(dynamic_cast(Constraints->getElement(i)) && - "Constraints list should contain constraint definitions!"); - Record *Constraint = - static_cast(Constraints->getElement(i))->getDef(); - TypeConstraints.push_back(Constraint); - } + std::vector ConstraintList = + TypeProfile->getValueAsListOfDefs("Constraints"); + TypeConstraints.assign(ConstraintList.begin(), ConstraintList.end()); } //===----------------------------------------------------------------------===// @@ -291,8 +284,13 @@ return true; } - TP.error("Type inference contradiction found in node " + - getOperator()->getName() + "!"); + if (isLeaf()) { + dump(); + TP.error("Type inference contradiction found in node!"); + } else { + TP.error("Type inference contradiction found in node " + + getOperator()->getName() + "!"); + } return true; // unreachable } @@ -462,10 +460,12 @@ // Pattern fragment types will be resolved when they are inlined. return MVT::isUnknown; } else if (R->isSubClassOf("Register")) { - assert(0 && "Explicit registers not handled here yet!\n"); + //const CodeGenTarget &T = TP.getDAGISelEmitter().getTargetInfo(); + // TODO: if a register appears in exactly one regclass, we could use that + // type info. return MVT::isUnknown; - } else if (R->isSubClassOf("ValueType")) { - // Using a VTSDNode. + } else if (R->isSubClassOf("ValueType") || R->isSubClassOf("CondCode")) { + // Using a VTSDNode or CondCodeSDNode. return MVT::Other; } else if (R->getName() == "node") { // Placeholder. @@ -482,10 +482,28 @@ /// exception. bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { if (isLeaf()) { - if (DefInit *DI = dynamic_cast(getLeafValue())) + if (DefInit *DI = dynamic_cast(getLeafValue())) { // If it's a regclass or something else known, include the type. return UpdateNodeType(getIntrinsicType(DI->getDef(), NotRegisters, TP), TP); + } else if (IntInit *II = dynamic_cast(getLeafValue())) { + // Int inits are always integers. :) + bool MadeChange = UpdateNodeType(MVT::isInt, TP); + + if (hasTypeSet()) { + unsigned Size = MVT::getSizeInBits(getType()); + // Make sure that the value is representable for this type. + if (Size < 32) { + int Val = (II->getValue() << (32-Size)) >> (32-Size); + if (Val != II->getValue()) + TP.error("Sign-extended integer value '" + itostr(II->getValue()) + + "' is out of range for type 'MVT::" + + getEnumName(getType()) + "'!"); + } + } + + return MadeChange; + } return false; } @@ -571,19 +589,22 @@ // TreePattern implementation // -TreePattern::TreePattern(Record *TheRec, ListInit *RawPat, +TreePattern::TreePattern(Record *TheRec, ListInit *RawPat, bool isInput, DAGISelEmitter &ise) : TheRecord(TheRec), ISE(ise) { + isInputPattern = isInput; for (unsigned i = 0, e = RawPat->getSize(); i != e; ++i) Trees.push_back(ParseTreePattern((DagInit*)RawPat->getElement(i))); } -TreePattern::TreePattern(Record *TheRec, DagInit *Pat, +TreePattern::TreePattern(Record *TheRec, DagInit *Pat, bool isInput, DAGISelEmitter &ise) : TheRecord(TheRec), ISE(ise) { + isInputPattern = isInput; Trees.push_back(ParseTreePattern(Pat)); } -TreePattern::TreePattern(Record *TheRec, TreePatternNode *Pat, +TreePattern::TreePattern(Record *TheRec, TreePatternNode *Pat, bool isInput, DAGISelEmitter &ise) : TheRecord(TheRec), ISE(ise) { + isInputPattern = isInput; Trees.push_back(Pat); } @@ -618,6 +639,10 @@ New = new TreePatternNode(DI); } else if (DagInit *DI = dynamic_cast(Arg)) { New = ParseTreePattern(DI); + } else if (IntInit *II = dynamic_cast(Arg)) { + New = new TreePatternNode(II); + if (!Dag->getArgName(0).empty()) + error("Constant int argument should not have a name!"); } else { Arg->dump(); error("Unknown leaf value for tree pattern!"); @@ -636,6 +661,11 @@ Operator->getName() != "set") error("Unrecognized node '" + Operator->getName() + "'!"); + // Check to see if this is something that is illegal in an input pattern. + if (isInputPattern && (Operator->isSubClassOf("Instruction") || + Operator->isSubClassOf("SDNodeXForm"))) + error("Cannot use '" + Operator->getName() + "' in an input pattern!"); + std::vector Children; for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) { @@ -663,8 +693,15 @@ Args.push_back(Dag->getArgName(i)); } } + } else if (IntInit *II = dynamic_cast(Arg)) { + TreePatternNode *Node = new TreePatternNode(II); + if (!Dag->getArgName(i).empty()) + error("Constant int argument should not have a name!"); + Children.push_back(Node); } else { + std::cerr << '"'; Arg->dump(); + std::cerr << "\": "; error("Unknown leaf value for tree pattern!"); } } @@ -771,7 +808,7 @@ OS << "\n// Predicate functions.\n"; for (unsigned i = 0, e = Fragments.size(); i != e; ++i) { DagInit *Tree = Fragments[i]->getValueAsDag("Fragment"); - TreePattern *P = new TreePattern(Fragments[i], Tree, *this); + TreePattern *P = new TreePattern(Fragments[i], Tree, true, *this); PatternFragments[Fragments[i]] = P; // Validate the argument list, converting it to map, to discard duplicates. @@ -975,14 +1012,39 @@ std::vector Instrs = Records.getAllDerivedDefinitions("Instruction"); for (unsigned i = 0, e = Instrs.size(); i != e; ++i) { - if (!dynamic_cast(Instrs[i]->getValueInit("Pattern"))) - continue; // no pattern yet, ignore it. + ListInit *LI = 0; - ListInit *LI = Instrs[i]->getValueAsListInit("Pattern"); - if (LI->getSize() == 0) continue; // no pattern. + if (dynamic_cast(Instrs[i]->getValueInit("Pattern"))) + LI = Instrs[i]->getValueAsListInit("Pattern"); + + // If there is no pattern, only collect minimal information about the + // instruction for its operand list. We have to assume that there is one + // result, as we have no detailed info. + if (!LI || LI->getSize() == 0) { + std::vector ResultTypes; + std::vector OperandTypes; + + CodeGenInstruction &InstInfo =Target.getInstruction(Instrs[i]->getName()); + + // Doesn't even define a result? + if (InstInfo.OperandList.size() == 0) + continue; + + // Assume the first operand is the result. + ResultTypes.push_back(InstInfo.OperandList[0].Ty); + + // The rest are inputs. + for (unsigned j = 1, e = InstInfo.OperandList.size(); j != e; ++j) + OperandTypes.push_back(InstInfo.OperandList[j].Ty); + + // Create and insert the instruction. + Instructions.insert(std::make_pair(Instrs[i], + DAGInstruction(0, ResultTypes, OperandTypes))); + continue; // no pattern. + } // Parse the instruction. - TreePattern *I = new TreePattern(Instrs[i], LI, *this); + TreePattern *I = new TreePattern(Instrs[i], LI, true, *this); // Inline pattern fragments into it. I->InlinePatternFragments(); @@ -1099,7 +1161,7 @@ // Use a temporary tree pattern to infer all types and make sure that the // constructed result is correct. This depends on the instruction already // being inserted into the Instructions map. - TreePattern Temp(I->getRecord(), ResultPattern, *this); + TreePattern Temp(I->getRecord(), ResultPattern, false, *this); Temp.InferAllTypes(); DAGInstruction &TheInsertedInst = Instructions.find(I->getRecord())->second; @@ -1112,6 +1174,7 @@ for (std::map::iterator II = Instructions.begin(), E = Instructions.end(); II != E; ++II) { TreePattern *I = II->second.getPattern(); + if (I == 0) continue; // No pattern. if (I->getNumTrees() != 1) { std::cerr << "CANNOT HANDLE: " << I->getRecord()->getName() << " yet!"; @@ -1140,7 +1203,7 @@ for (unsigned i = 0, e = Patterns.size(); i != e; ++i) { DagInit *Tree = Patterns[i]->getValueAsDag("PatternToMatch"); - TreePattern *Pattern = new TreePattern(Patterns[i], Tree, *this); + TreePattern *Pattern = new TreePattern(Patterns[i], Tree, true, *this); // Inline pattern fragments into it. Pattern->InlinePatternFragments(); @@ -1154,7 +1217,7 @@ if (LI->getSize() == 0) continue; // no pattern. // Parse the instruction. - TreePattern *Result = new TreePattern(Patterns[i], LI, *this); + TreePattern *Result = new TreePattern(Patterns[i], LI, false, *this); // Inline pattern fragments into it. Result->InlinePatternFragments(); @@ -1437,6 +1500,9 @@ TreePatternNode *Child = P->getChild(i); if (!Child->isLeaf() && Child->getExtType() != MVT::Other) Size += getPatternSize(Child); + else if (Child->isLeaf() && dynamic_cast(Child->getLeafValue())) { + ++Size; // Matches a ConstantSDNode. + } } return Size; @@ -1477,7 +1543,16 @@ const std::string &RootName, std::map &VarMap, unsigned PatternNo, std::ostream &OS) { - assert(!N->isLeaf() && "Cannot match against a leaf!"); + if (N->isLeaf()) { + if (IntInit *II = dynamic_cast(N->getLeafValue())) { + OS << " if (cast(" << RootName + << ")->getSignExtended() != " << II->getValue() << ")\n" + << " goto P" << PatternNo << "Fail;\n"; + return; + } + assert(0 && "Cannot match this as a leaf value!"); + abort(); + } // If this node has a name associated with it, capture it in VarMap. If // we already saw this in the pattern, emit code to verify dagness. @@ -1527,15 +1602,29 @@ } // Handle leaves of various types. - Init *LeafVal = Child->getLeafValue(); - Record *LeafRec = dynamic_cast(LeafVal)->getDef(); - if (LeafRec->isSubClassOf("RegisterClass")) { - // Handle register references. Nothing to do here. - } else if (LeafRec->isSubClassOf("ValueType")) { - // Make sure this is the specified value type. - OS << " if (cast(" << RootName << i << ")->getVT() != " - << "MVT::" << LeafRec->getName() << ") goto P" << PatternNo - << "Fail;\n"; + if (DefInit *DI = dynamic_cast(Child->getLeafValue())) { + Record *LeafRec = DI->getDef(); + if (LeafRec->isSubClassOf("RegisterClass")) { + // Handle register references. Nothing to do here. + } else if (LeafRec->isSubClassOf("ValueType")) { + // Make sure this is the specified value type. + OS << " if (cast(" << RootName << i << ")->getVT() != " + << "MVT::" << LeafRec->getName() << ") goto P" << PatternNo + << "Fail;\n"; + } else if (LeafRec->isSubClassOf("CondCode")) { + // Make sure this is the specified cond code. + OS << " if (cast(" << RootName << i + << ")->get() != " << "ISD::" << LeafRec->getName() + << ") goto P" << PatternNo << "Fail;\n"; + } else { + Child->dump(); + assert(0 && "Unknown leaf type!"); + } + } else if (IntInit *II = dynamic_cast(Child->getLeafValue())) { + OS << " if (!isa(" << RootName << i << ") ||\n" + << " cast(" << RootName << i + << ")->getSignExtended() != " << II->getValue() << ")\n" + << " goto P" << PatternNo << "Fail;\n"; } else { Child->dump(); assert(0 && "Unknown leaf type!"); @@ -1589,6 +1678,25 @@ } if (N->isLeaf()) { + // If this is an explicit register reference, handle it. + if (DefInit *DI = dynamic_cast(N->getLeafValue())) { + unsigned ResNo = Ctr++; + if (DI->getDef()->isSubClassOf("Register")) { + OS << " SDOperand Tmp" << ResNo << " = CurDAG->getRegister(" + << getQualifiedName(DI->getDef()) << ", MVT::" + << getEnumName(N->getType()) + << ");\n"; + return ResNo; + } + } else if (IntInit *II = dynamic_cast(N->getLeafValue())) { + unsigned ResNo = Ctr++; + OS << " SDOperand Tmp" << ResNo << " = CurDAG->getTargetConstant(" + << II->getValue() << ", MVT::" + << getEnumName(N->getType()) + << ");\n"; + return ResNo; + } + N->dump(); assert(0 && "Unknown leaf type!"); return ~0U; @@ -1685,6 +1793,12 @@ return false; } +Record *DAGISelEmitter::getSDNodeNamed(const std::string &Name) const { + Record *N = Records.getDef(Name); + assert(N && N->isSubClassOf("SDNode") && "Bad argument"); + return N; +} + /// EmitCodeForPattern - Given a pattern to match, emit code to the specified /// stream to match the pattern, and generate the code for the match if it /// succeeds. @@ -1785,14 +1899,52 @@ << " SDOperand Tmp0 = Select(N.getOperand(0));\n" << " if (!N.Val->hasOneUse()) CodeGenMap[N] = Tmp0;\n" << " return Tmp0;\n" + << " }\n" + << " case ISD::TokenFactor:\n" + << " if (N.getNumOperands() == 2) {\n" + << " SDOperand Op0 = Select(N.getOperand(0));\n" + << " SDOperand Op1 = Select(N.getOperand(1));\n" + << " return CodeGenMap[N] =\n" + << " CurDAG->getNode(ISD::TokenFactor, MVT::Other, Op0, Op1);\n" + << " } else {\n" + << " std::vector Ops;\n" + << " for (unsigned i = 0, e = N.getNumOperands(); i != e; ++i)\n" + << " Ops.push_back(Select(N.getOperand(i)));\n" + << " return CodeGenMap[N] = \n" + << " CurDAG->getNode(ISD::TokenFactor, MVT::Other, Ops);\n" + << " }\n" + << " case ISD::CopyFromReg: {\n" + << " SDOperand Chain = Select(N.getOperand(0));\n" + << " if (Chain == N.getOperand(0)) return N; // No change\n" + << " SDOperand New = CurDAG->getCopyFromReg(Chain,\n" + << " cast(N.getOperand(1))->getReg(),\n" + << " N.Val->getValueType(0));\n" + << " return New.getValue(N.ResNo);\n" + << " }\n" + << " case ISD::CopyToReg: {\n" + << " SDOperand Chain = Select(N.getOperand(0));\n" + << " SDOperand Reg = N.getOperand(1);\n" + << " SDOperand Val = Select(N.getOperand(2));\n" + << " return CodeGenMap[N] = \n" + << " CurDAG->getNode(ISD::CopyToReg, MVT::Other,\n" + << " Chain, Reg, Val);\n" << " }\n"; // Group the patterns by their top-level opcodes. std::map, CompareByRecordName> PatternsByOpcode; for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) - PatternsByOpcode[PatternsToMatch[i].first->getOperator()] - .push_back(&PatternsToMatch[i]); + if (!PatternsToMatch[i].first->isLeaf()) { + PatternsByOpcode[PatternsToMatch[i].first->getOperator()] + .push_back(&PatternsToMatch[i]); + } else { + if (IntInit *II = + dynamic_cast(PatternsToMatch[i].first->getLeafValue())) { + PatternsByOpcode[getSDNodeNamed("imm")].push_back(&PatternsToMatch[i]); + } else { + assert(0 && "Unknown leaf value"); + } + } // Loop over all of the case statements. for (std::map, Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.33 llvm/utils/TableGen/DAGISelEmitter.h:1.33.2.1 --- llvm/utils/TableGen/DAGISelEmitter.h:1.33 Sat Oct 15 20:41:58 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Wed Nov 16 12:33:45 2005 @@ -226,7 +226,7 @@ /// ContainsUnresolvedType - Return true if this tree contains any /// unresolved types. bool ContainsUnresolvedType() const { - if (Ty == MVT::LAST_VALUETYPE) return true; + if (!hasTypeSet()) return true; for (unsigned i = 0, e = getNumChildren(); i != e; ++i) if (getChild(i)->ContainsUnresolvedType()) return true; return false; @@ -258,13 +258,20 @@ /// ISE - the DAG isel emitter coordinating this madness. /// DAGISelEmitter &ISE; + + /// isInputPattern - True if this is an input pattern, something to match. + /// False if this is an output pattern, something to emit. + bool isInputPattern; public: /// TreePattern constructor - Parse the specified DagInits into the /// current record. - TreePattern(Record *TheRec, ListInit *RawPat, DAGISelEmitter &ise); - TreePattern(Record *TheRec, DagInit *Pat, DAGISelEmitter &ise); - TreePattern(Record *TheRec, TreePatternNode *Pat, DAGISelEmitter &ise); + TreePattern(Record *TheRec, ListInit *RawPat, bool isInput, + DAGISelEmitter &ise); + TreePattern(Record *TheRec, DagInit *Pat, bool isInput, + DAGISelEmitter &ise); + TreePattern(Record *TheRec, TreePatternNode *Pat, bool isInput, + DAGISelEmitter &ise); /// getTrees - Return the tree patterns which corresponds to this pattern. /// @@ -375,6 +382,8 @@ const CodeGenTarget &getTargetInfo() const { return Target; } + Record *getSDNodeNamed(const std::string &Name) const; + const SDNodeInfo &getSDNodeInfo(Record *R) const { assert(SDNodes.count(R) && "Unknown node!"); return SDNodes.find(R)->second; Index: llvm/utils/TableGen/InstrInfoEmitter.cpp diff -u llvm/utils/TableGen/InstrInfoEmitter.cpp:1.28 llvm/utils/TableGen/InstrInfoEmitter.cpp:1.28.2.1 --- llvm/utils/TableGen/InstrInfoEmitter.cpp:1.28 Fri Aug 26 15:42:52 2005 +++ llvm/utils/TableGen/InstrInfoEmitter.cpp Wed Nov 16 12:33:45 2005 @@ -15,6 +15,7 @@ #include "InstrInfoEmitter.h" #include "CodeGenTarget.h" #include "Record.h" +#include using namespace llvm; // runEnums - Print out enum values for all of the instructions. @@ -47,16 +48,6 @@ OS << "} // End llvm namespace \n"; } -static std::vector GetDefList(ListInit *LI, const std::string &Name) { - std::vector Result; - for (unsigned i = 0, e = LI->getSize(); i != e; ++i) - if (DefInit *DI = dynamic_cast(LI->getElement(i))) - Result.push_back(DI->getDef()); - else - throw "Illegal value in '" + Name + "' list!"; - return Result; -} - void InstrInfoEmitter::printDefList(const std::vector &Uses, unsigned Num, std::ostream &OS) const { OS << "static const unsigned ImplicitList" << Num << "[] = { "; @@ -86,6 +77,8 @@ // run - Emit the main instruction description records for the target... void InstrInfoEmitter::run(std::ostream &OS) { + GatherItinClasses(); + EmitSourceFileHeader("Target Instruction Descriptors", OS); OS << "namespace llvm {\n\n"; @@ -99,26 +92,21 @@ // Keep track of all of the def lists we have emitted already. std::map, unsigned> EmittedLists; - std::map ListNumbers; unsigned ListNumber = 0; // Emit all of the instruction's implicit uses and defs. for (CodeGenTarget::inst_iterator II = Target.inst_begin(), E = Target.inst_end(); II != E; ++II) { Record *Inst = II->second.TheDef; - ListInit *LI = Inst->getValueAsListInit("Uses"); - if (LI->getSize()) { - std::vector Uses = GetDefList(LI, Inst->getName()); + std::vector Uses = Inst->getValueAsListOfDefs("Uses"); + if (!Uses.empty()) { unsigned &IL = EmittedLists[Uses]; if (!IL) printDefList(Uses, IL = ++ListNumber, OS); - ListNumbers[LI] = IL; } - LI = Inst->getValueAsListInit("Defs"); - if (LI->getSize()) { - std::vector Uses = GetDefList(LI, Inst->getName()); - unsigned &IL = EmittedLists[Uses]; - if (!IL) printDefList(Uses, IL = ++ListNumber, OS); - ListNumbers[LI] = IL; + std::vector Defs = Inst->getValueAsListOfDefs("Defs"); + if (!Defs.empty()) { + unsigned &IL = EmittedLists[Defs]; + if (!IL) printDefList(Defs, IL = ++ListNumber, OS); } } @@ -150,14 +138,14 @@ // OS << "\nstatic const TargetInstrDescriptor " << TargetName << "Insts[] = {\n"; - emitRecord(Target.getPHIInstruction(), 0, InstrInfo, ListNumbers, + emitRecord(Target.getPHIInstruction(), 0, InstrInfo, EmittedLists, OperandInfosEmitted, OS); unsigned i = 0; for (CodeGenTarget::inst_iterator II = Target.inst_begin(), E = Target.inst_end(); II != E; ++II) if (II->second.TheDef != PHI) - emitRecord(II->second, ++i, InstrInfo, ListNumbers, + emitRecord(II->second, ++i, InstrInfo, EmittedLists, OperandInfosEmitted, OS); OS << "};\n"; OS << "} // End llvm namespace \n"; @@ -165,7 +153,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, - std::map &ListNumbers, + std::map, unsigned> &EmittedLists, std::map, unsigned> &OpInfo, std::ostream &OS) { int NumOperands; @@ -183,7 +171,13 @@ OS << Inst.TheDef->getName(); else OS << Inst.Name; - OS << "\",\t" << NumOperands << ", -1, 0, false, 0, 0, 0, 0"; + + unsigned ItinClass = !IsItineraries ? 0 : + ItinClassNumber(Inst.TheDef->getValueAsDef("Itinerary")->getName()); + + OS << "\",\t" << NumOperands << ", -1, 0, false, 0, 0, " + << ItinClass + << ", 0"; // Emit all of the target indepedent flags... if (Inst.isReturn) OS << "|M_RET_FLAG"; @@ -215,17 +209,17 @@ OS << ", "; // Emit the implicit uses and defs lists... - LI = Inst.TheDef->getValueAsListInit("Uses"); - if (!LI->getSize()) + std::vector UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); + if (UseList.empty()) OS << "EmptyImpList, "; else - OS << "ImplicitList" << ListNumbers[LI] << ", "; + OS << "ImplicitList" << EmittedLists[UseList] << ", "; - LI = Inst.TheDef->getValueAsListInit("Defs"); - if (!LI->getSize()) + std::vector DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); + if (DefList.empty()) OS << "EmptyImpList, "; else - OS << "ImplicitList" << ListNumbers[LI] << ", "; + OS << "ImplicitList" << EmittedLists[DefList] << ", "; // Emit the operand info. std::vector OperandInfo = GetOperandInfo(Inst); @@ -237,6 +231,30 @@ OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; } +struct LessRecord { + bool operator()(const Record *Rec1, const Record *Rec2) const { + return Rec1->getName() < Rec2->getName(); + } +}; +void InstrInfoEmitter::GatherItinClasses() { + std::vector DefList = + Records.getAllDerivedDefinitions("InstrItinClass"); + IsItineraries = !DefList.empty(); + + if (!IsItineraries) return; + + sort(DefList.begin(), DefList.end(), LessRecord()); + + for (unsigned i = 0, N = DefList.size(); i < N; i++) { + Record *Def = DefList[i]; + ItinClassMap[Def->getName()] = i; + } +} + +unsigned InstrInfoEmitter::ItinClassNumber(std::string ItinName) { + return ItinClassMap[ItinName]; +} + void InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val, IntInit *ShiftInt, std::ostream &OS) { if (Val == 0 || ShiftInt == 0) Index: llvm/utils/TableGen/InstrInfoEmitter.h diff -u llvm/utils/TableGen/InstrInfoEmitter.h:1.10 llvm/utils/TableGen/InstrInfoEmitter.h:1.10.2.1 --- llvm/utils/TableGen/InstrInfoEmitter.h:1.10 Fri Aug 19 13:46:26 2005 +++ llvm/utils/TableGen/InstrInfoEmitter.h Wed Nov 16 12:33:45 2005 @@ -28,8 +28,11 @@ class InstrInfoEmitter : public TableGenBackend { RecordKeeper &Records; + bool IsItineraries; + std::map ItinClassMap; + public: - InstrInfoEmitter(RecordKeeper &R) : Records(R) {} + InstrInfoEmitter(RecordKeeper &R) : Records(R), IsItineraries(false) {} // run - Output the instruction set description, returning true on failure. void run(std::ostream &OS); @@ -41,9 +44,11 @@ std::ostream &OS) const; void emitRecord(const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, - std::map &ListNumbers, + std::map, unsigned> &EL, std::map, unsigned> &OpInfo, std::ostream &OS); + void GatherItinClasses(); + unsigned ItinClassNumber(std::string ItinName); void emitShiftedValue(Record *R, StringInit *Val, IntInit *Shift, std::ostream &OS); }; Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.45 llvm/utils/TableGen/Record.cpp:1.45.2.1 --- llvm/utils/TableGen/Record.cpp:1.45 Tue Sep 13 16:44:28 2005 +++ llvm/utils/TableGen/Record.cpp Wed Nov 16 12:33:45 2005 @@ -709,6 +709,25 @@ "' does not have a list initializer!"; } +/// getValueAsListOfDefs - This method looks up the specified field and returns +/// its value as a vector of records, throwing an exception if the field does +/// not exist or if the value is not the right type. +/// +std::vector +Record::getValueAsListOfDefs(const std::string &FieldName) const { + ListInit *List = getValueAsListInit(FieldName); + std::vector Defs; + for (unsigned i = 0; i < List->getSize(); i++) { + if (DefInit *DI = dynamic_cast(List->getElement(i))) { + Defs.push_back(DI->getDef()); + } else { + throw "Record `" + getName() + "', field `" + FieldName + + "' list is not entirely DefInit!"; + } + } + return Defs; +} + /// getValueAsInt - This method looks up the specified field and returns its /// value as an int, throwing an exception if the field does not exist or if /// the value is not the right type. Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.52 llvm/utils/TableGen/Record.h:1.52.2.1 --- llvm/utils/TableGen/Record.h:1.52 Tue Sep 13 16:44:28 2005 +++ llvm/utils/TableGen/Record.h Wed Nov 16 12:33:45 2005 @@ -1000,6 +1000,12 @@ /// ListInit *getValueAsListInit(const std::string &FieldName) const; + /// getValueAsListOfDefs - This method looks up the specified field and + /// returnsits value as a vector of records, throwing an exception if the + /// field does not exist or if the value is not the right type. + /// + std::vector getValueAsListOfDefs(const std::string &FieldName) const; + /// getValueAsDef - This method looks up the specified field and returns its /// value as a Record, throwing an exception if the field does not exist or if /// the value is not the right type. Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp diff -u llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.36 llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.36.2.1 --- llvm/utils/TableGen/RegisterInfoEmitter.cpp:1.36 Sun Oct 2 01:23:37 2005 +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp Wed Nov 16 12:33:45 2005 @@ -163,23 +163,22 @@ for (unsigned i = 0, e = Regs.size(); i != e; ++i) { Record *R = Regs[i].TheDef; - ListInit *LI = Regs[i].TheDef->getValueAsListInit("Aliases"); + std::vector LI = Regs[i].TheDef->getValueAsListOfDefs("Aliases"); // Add information that R aliases all of the elements in the list... and // that everything in the list aliases R. - for (unsigned j = 0, e = LI->getSize(); j != e; ++j) { - DefInit *Reg = dynamic_cast(LI->getElement(j)); - if (!Reg) throw "ERROR: Alias list element is not a def!"; - if (RegisterAliases[R].count(Reg->getDef())) + for (unsigned j = 0, e = LI.size(); j != e; ++j) { + Record *Reg = LI[j]; + if (RegisterAliases[R].count(Reg)) std::cerr << "Warning: register alias between " << getQualifiedName(R) - << " and " << getQualifiedName(Reg->getDef()) + << " and " << getQualifiedName(Reg) << " specified multiple times!\n"; - RegisterAliases[R].insert(Reg->getDef()); + RegisterAliases[R].insert(Reg); - if (RegisterAliases[Reg->getDef()].count(R)) + if (RegisterAliases[Reg].count(R)) std::cerr << "Warning: register alias between " << getQualifiedName(R) - << " and " << getQualifiedName(Reg->getDef()) + << " and " << getQualifiedName(Reg) << " specified multiple times!\n"; - RegisterAliases[Reg->getDef()].insert(R); + RegisterAliases[Reg].insert(R); } } Index: llvm/utils/TableGen/SubtargetEmitter.cpp diff -c /dev/null llvm/utils/TableGen/SubtargetEmitter.cpp:1.14.2.2 *** /dev/null Wed Nov 16 12:33:56 2005 --- llvm/utils/TableGen/SubtargetEmitter.cpp Wed Nov 16 12:33:45 2005 *************** *** 0 **** --- 1,516 ---- + //===- SubtargetEmitter.cpp - Generate subtarget enumerations -------------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by James M. Laskey and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This tablegen backend emits subtarget enumerations. The format is in a state + // flux and will be tightened up when integration to scheduling is complete. + // + //===----------------------------------------------------------------------===// + + #include "SubtargetEmitter.h" + #include "CodeGenTarget.h" + #include "Record.h" + #include "llvm/ADT/StringExtras.h" + #include "llvm/Support/Debug.h" + #include + using namespace llvm; + + // + // Record sort by name function. + // + struct LessRecord { + bool operator()(const Record *Rec1, const Record *Rec2) const { + return Rec1->getName() < Rec2->getName(); + } + }; + + // + // Record sort by field "Name" function. + // + struct LessRecordFieldName { + bool operator()(const Record *Rec1, const Record *Rec2) const { + return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name"); + } + }; + + // + // Enumeration - Emit the specified class as an enumeration. + // + void SubtargetEmitter::Enumeration(std::ostream &OS, + const char *ClassName, + bool isBits) { + // Get all records of class and sort + std::vector DefList = Records.getAllDerivedDefinitions(ClassName); + sort(DefList.begin(), DefList.end(), LessRecord()); + + // Open enumeration + OS << "enum {\n"; + + // For each record + for (unsigned i = 0, N = DefList.size(); i < N;) { + // Next record + Record *Def = DefList[i]; + + // Get and emit name + std::string Name = Def->getName(); + OS << " " << Name; + + // If bit flags then emit expression (1 << i) + if (isBits) OS << " = " << " 1 << " << i; + + // Depending on 'if more in the list' emit comma + if (++i < N) OS << ","; + + OS << "\n"; + } + + // Close enumeration + OS << "};\n"; + } + + // + // FeatureKeyValues - Emit data of all the subtarget features. Used by command + // line. + // + void SubtargetEmitter::FeatureKeyValues(std::ostream &OS) { + // Gather and sort all the features + std::vector FeatureList = + Records.getAllDerivedDefinitions("SubtargetFeature"); + sort(FeatureList.begin(), FeatureList.end(), LessRecord()); + + // Begin feature table + OS << "// Sorted (by key) array of values for CPU features.\n" + << "static llvm::SubtargetFeatureKV FeatureKV[] = {\n"; + + // For each feature + for (unsigned i = 0, N = FeatureList.size(); i < N;) { + // Next feature + Record *Feature = FeatureList[i]; + + std::string Name = Feature->getName(); + std::string CommandLineName = Feature->getValueAsString("Name"); + std::string Desc = Feature->getValueAsString("Desc"); + + // Emit as { "feature", "decription", feactureEnum } + OS << " { " + << "\"" << CommandLineName << "\", " + << "\"" << Desc << "\", " + << Name + << " }"; + + // Depending on 'if more in the list' emit comma + if (++i < N) OS << ","; + + OS << "\n"; + } + + // End feature table + OS << "};\n"; + + // Emit size of table + OS<<"\nenum {\n"; + OS<<" FeatureKVSize = sizeof(FeatureKV)/sizeof(llvm::SubtargetFeatureKV)\n"; + OS<<"};\n"; + } + + // + // CPUKeyValues - Emit data of all the subtarget processors. Used by command + // line. + // + void SubtargetEmitter::CPUKeyValues(std::ostream &OS) { + // Gather and sort processor information + std::vector ProcessorList = + Records.getAllDerivedDefinitions("Processor"); + sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName()); + + // Begin processor table + OS << "// Sorted (by key) array of values for CPU subtype.\n" + << "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n"; + + // For each processor + for (unsigned i = 0, N = ProcessorList.size(); i < N;) { + // Next processor + Record *Processor = ProcessorList[i]; + + std::string Name = Processor->getValueAsString("Name"); + std::vector FeatureList = + Processor->getValueAsListOfDefs("Features"); + + // Emit as { "cpu", "description", f1 | f2 | ... fn }, + OS << " { " + << "\"" << Name << "\", " + << "\"Select the " << Name << " processor\", "; + + if (FeatureList.empty()) { + OS << "0"; + } else { + for (unsigned j = 0, M = FeatureList.size(); j < M;) { + Record *Feature = FeatureList[j]; + std::string Name = Feature->getName(); + OS << Name; + if (++j < M) OS << " | "; + } + } + + OS << " }"; + + // Depending on 'if more in the list' emit comma + if (++i < N) OS << ","; + + OS << "\n"; + } + + // End processor table + OS << "};\n"; + + // Emit size of table + OS<<"\nenum {\n"; + OS<<" SubTypeKVSize = sizeof(SubTypeKV)/sizeof(llvm::SubtargetFeatureKV)\n"; + OS<<"};\n"; + } + + // + // CollectAllItinClasses - Gathers and enumerates all the itinerary classes. + // Returns itinerary class count. + // + unsigned SubtargetEmitter::CollectAllItinClasses(std::ostream &OS, + std::map &ItinClassesMap) { + // Gather and sort all itinerary classes + std::vector ItinClassList = + Records.getAllDerivedDefinitions("InstrItinClass"); + sort(ItinClassList.begin(), ItinClassList.end(), LessRecord()); + + // For each itinerary class + unsigned N = ItinClassList.size(); + for (unsigned i = 0; i < N; i++) { + // Next itinerary class + Record *ItinClass = ItinClassList[i]; + // Get name of itinerary class + std::string Name = ItinClass->getName(); + // Assign itinerary class a unique number + ItinClassesMap[Name] = i; + } + + // Emit size of table + OS<<"\nenum {\n"; + OS<<" ItinClassesSize = " << N << "\n"; + OS<<"};\n"; + + // Return itinerary class count + return N; + } + + // + // FormItineraryString - Compose a string containing the data initialization + // for the specified itinerary. N is the number of stages. + // + void SubtargetEmitter::FormItineraryString(Record *ItinData, + std::string &ItinString, + unsigned &NStages) { + // Get states list + std::vector StageList = ItinData->getValueAsListOfDefs("Stages"); + + // For each stage + unsigned N = NStages = StageList.size(); + for (unsigned i = 0; i < N; i++) { + // Next stage + Record *Stage = StageList[i]; + + // Form string as ,{ cycles, u1 | u2 | ... | un } + int Cycles = Stage->getValueAsInt("Cycles"); + ItinString += " { " + itostr(Cycles) + ", "; + + // Get unit list + std::vector UnitList = Stage->getValueAsListOfDefs("Units"); + + // For each unit + for (unsigned j = 0, M = UnitList.size(); j < M;) { + // Next unit + Record *Unit = UnitList[j]; + + // Add name and bitwise or + ItinString += Unit->getName(); + if (++j < M) ItinString += " | "; + } + + // Close off stage + ItinString += " }"; + } + } + + // + // EmitStageData - Generate unique itinerary stages. Record itineraries for + // processors. + // + void SubtargetEmitter::EmitStageData(std::ostream &OS, + unsigned NItinClasses, + std::map &ItinClassesMap, + std::vector > &ProcList) { + // Gather processor iteraries + std::vector ProcItinList = + Records.getAllDerivedDefinitions("ProcessorItineraries"); + + // If just no itinerary then don't bother + if (ProcItinList.size() < 2) return; + + // Begin stages table + OS << "static llvm::InstrStage Stages[] = {\n" + " { 0, 0 }, // No itinerary\n"; + + unsigned ItinEnum = 1; + std::map ItinMap; + for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) { + // Next record + Record *Proc = ProcItinList[i]; + + // Get processor itinerary name + std::string Name = Proc->getName(); + + // Skip default + if (Name == "NoItineraries") continue; + + // Create and expand processor itinerary to cover all itinerary classes + std::vector ItinList; + ItinList.resize(NItinClasses); + + // Get itinerary data list + std::vector ItinDataList = Proc->getValueAsListOfDefs("IID"); + + // For each itinerary data + for (unsigned j = 0, M = ItinDataList.size(); j < M; j++) { + // Next itinerary data + Record *ItinData = ItinDataList[j]; + + // Get string and stage count + std::string ItinString; + unsigned NStages; + FormItineraryString(ItinData, ItinString, NStages); + + // Check to see if it already exists + unsigned Find = ItinMap[ItinString]; + + // If new itinerary + if (Find == 0) { + // Emit as { cycles, u1 | u2 | ... | un }, // index + OS << ItinString << ", // " << ItinEnum << "\n"; + // Record Itin class number + ItinMap[ItinString] = Find = ItinEnum++; + } + + // Set up itinerary as location and location + stage count + InstrItinerary Intinerary = { Find, Find + NStages }; + + // Locate where to inject into processor itinerary table + std::string Name = ItinData->getValueAsDef("TheClass")->getName(); + Find = ItinClassesMap[Name]; + + // Inject - empty slots will be 0, 0 + ItinList[Find] = Intinerary; + } + + // Add process itinerary to list + ProcList.push_back(ItinList); + } + + // Closing stage + OS << " { 0, 0 } // End itinerary\n"; + // End stages table + OS << "};\n"; + + // Emit size of table + OS<<"\nenum {\n"; + OS<<" StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage)\n"; + OS<<"};\n"; + } + + // + // EmitProcessorData - Generate data for processor itineraries. + // + void SubtargetEmitter::EmitProcessorData(std::ostream &OS, + std::vector > &ProcList) { + // Get an iterator for processor itinerary stages + std::vector >::iterator + ProcListIter = ProcList.begin(); + + // For each processor itinerary + std::vector Itins = + Records.getAllDerivedDefinitions("ProcessorItineraries"); + for (unsigned i = 0, N = Itins.size(); i < N; i++) { + // Next record + Record *Itin = Itins[i]; + + // Get processor itinerary name + std::string Name = Itin->getName(); + + // Skip default + if (Name == "NoItineraries") continue; + + // Begin processor itinerary table + OS << "\n"; + OS << "static llvm::InstrItinerary " << Name << "[] = {\n"; + + // For each itinerary class + std::vector &ItinList = *ProcListIter++; + unsigned ItinIndex = 0; + for (unsigned j = 0, M = ItinList.size(); j < M;) { + InstrItinerary &Intinerary = ItinList[j]; + + // Emit in the form of { first, last } // index + if (Intinerary.First == 0) { + OS << " { 0, 0 }"; + } else { + OS << " { " << Intinerary.First << ", " << Intinerary.Last << " }"; + } + + // If more in list add comma + if (++j < M) OS << ","; + + OS << " // " << (j - 1) << "\n"; + } + + // End processor itinerary table + OS << "};\n"; + } + + OS << "\n"; + OS << "static llvm::InstrItinerary NoItineraries[] = {};\n"; + } + + // + // EmitProcessorLookup - generate cpu name to itinerary lookup table. + // + void SubtargetEmitter::EmitProcessorLookup(std::ostream &OS) { + // Gather and sort processor information + std::vector ProcessorList = + Records.getAllDerivedDefinitions("Processor"); + sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName()); + + // Begin processor table + OS << "\n"; + OS << "// Sorted (by key) array of itineraries for CPU subtype.\n" + << "static const llvm::SubtargetInfoKV ProcItinKV[] = {\n"; + + // For each processor + for (unsigned i = 0, N = ProcessorList.size(); i < N;) { + // Next processor + Record *Processor = ProcessorList[i]; + + std::string Name = Processor->getValueAsString("Name"); + std::string ProcItin = Processor->getValueAsDef("ProcItin")->getName(); + + // Emit as { "cpu", procinit }, + OS << " { " + << "\"" << Name << "\", " + << "(void *)&" << ProcItin; + + OS << " }"; + + // Depending on ''if more in the list'' emit comma + if (++i < N) OS << ","; + + OS << "\n"; + } + + // End processor table + OS << "};\n"; + + // Emit size of table + OS<<"\nenum {\n"; + OS<<" ProcItinKVSize = sizeof(ProcItinKV)/" + "sizeof(llvm::SubtargetInfoKV)\n"; + OS<<"};\n"; + } + + // + // EmitData - Emits all stages and itineries, folding common patterns. + // + void SubtargetEmitter::EmitData(std::ostream &OS) { + std::map ItinClassesMap; + std::vector > ProcList; + + // Enumerate all the itinerary classes + unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap); + // Make sure the rest is worth the effort + HasItineraries = NItinClasses != 0; + + if (HasItineraries) { + // Emit the stage data + EmitStageData(OS, NItinClasses, ItinClassesMap, ProcList); + // Emit the processor itinerary data + EmitProcessorData(OS, ProcList); + // Emit the processor lookup data + EmitProcessorLookup(OS); + } + } + + // + // ParseFeaturesFunction - Produces a subtarget specific function for parsing + // the subtarget features string. + // + void SubtargetEmitter::ParseFeaturesFunction(std::ostream &OS) { + std::vector Features = + Records.getAllDerivedDefinitions("SubtargetFeature"); + sort(Features.begin(), Features.end(), LessRecord()); + + OS << "// ParseSubtargetFeatures - Parses features string setting specified\n" + "// subtarget options.\n" + "void llvm::"; + OS << Target; + OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n" + " const std::string &CPU) {\n" + " SubtargetFeatures Features(FS);\n" + " Features.setCPUIfNone(CPU);\n" + " uint32_t Bits = Features.getBits(SubTypeKV, SubTypeKVSize,\n" + " FeatureKV, FeatureKVSize);\n"; + + for (unsigned i = 0; i < Features.size(); i++) { + // Next record + Record *R = Features[i]; + std::string Instance = R->getName(); + std::string Name = R->getValueAsString("Name"); + std::string Type = R->getValueAsString("Type"); + std::string Attribute = R->getValueAsString("Attribute"); + + OS << " " << Attribute << " = (Bits & " << Instance << ") != 0;\n"; + } + + if (HasItineraries) { + OS << "\n" + << " InstrItinerary *Itinerary = (InstrItinerary *)" + "Features.getInfo(ProcItinKV, ProcItinKVSize);\n" + " InstrItins = InstrItineraryData(Stages, Itinerary);\n"; + } + + OS << "}\n"; + } + + // + // SubtargetEmitter::run - Main subtarget enumeration emitter. + // + void SubtargetEmitter::run(std::ostream &OS) { + Target = CodeGenTarget().getName(); + + EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS); + + OS << "#include \"llvm/Target/SubtargetFeature.h\"\n"; + OS << "#include \"llvm/Target/TargetInstrItineraries.h\"\n\n"; + + Enumeration(OS, "FuncUnit", true); + OS<<"\n"; + // Enumeration(OS, "InstrItinClass", false); + // OS<<"\n"; + Enumeration(OS, "SubtargetFeature", true); + OS<<"\n"; + FeatureKeyValues(OS); + OS<<"\n"; + CPUKeyValues(OS); + OS<<"\n"; + EmitData(OS); + OS<<"\n"; + ParseFeaturesFunction(OS); + } Index: llvm/utils/TableGen/SubtargetEmitter.h diff -c /dev/null llvm/utils/TableGen/SubtargetEmitter.h:1.7.2.2 *** /dev/null Wed Nov 16 12:33:56 2005 --- llvm/utils/TableGen/SubtargetEmitter.h Wed Nov 16 12:33:45 2005 *************** *** 0 **** --- 1,62 ---- + //===- SubtargetEmitter.h - Generate subtarget enumerations -----*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by James M. Laskey and is distributed under + // the University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This tablegen backend emits subtarget enumerations. + // + //===----------------------------------------------------------------------===// + + #ifndef SUBTARGET_EMITTER_H + #define SUBTARGET_EMITTER_H + + #include "TableGenBackend.h" + #include "llvm/Target/TargetInstrItineraries.h" + #include + #include + #include + + + namespace llvm { + + class SubtargetEmitter : public TableGenBackend { + + RecordKeeper &Records; + std::string Target; + bool HasItineraries; + + void Enumeration(std::ostream &OS, const char *ClassName, bool isBits); + void FeatureKeyValues(std::ostream &OS); + void CPUKeyValues(std::ostream &OS); + unsigned CollectAllItinClasses(std::ostream &OS, + std::map &ItinClassesMap); + void FormItineraryString(Record *ItinData, std::string &ItinString, + unsigned &NStages); + void EmitStageData(std::ostream &OS, unsigned NItinClasses, + std::map &ItinClassesMap, + std::vector > &ProcList); + void EmitProcessorData(std::ostream &OS, + std::vector > &ProcList); + void EmitProcessorLookup(std::ostream &OS); + void EmitData(std::ostream &OS); + void ParseFeaturesFunction(std::ostream &OS); + + public: + SubtargetEmitter(RecordKeeper &R) : Records(R), HasItineraries(false) {} + + // run - Output the subtarget enumerations, returning true on failure. + void run(std::ostream &o); + + }; + + + } // End llvm namespace + + #endif + + + Index: llvm/utils/TableGen/TableGen.cpp diff -u llvm/utils/TableGen/TableGen.cpp:1.39 llvm/utils/TableGen/TableGen.cpp:1.39.2.1 --- llvm/utils/TableGen/TableGen.cpp:1.39 Fri Sep 2 20:14:03 2005 +++ llvm/utils/TableGen/TableGen.cpp Wed Nov 16 12:33:45 2005 @@ -23,8 +23,8 @@ #include "RegisterInfoEmitter.h" #include "InstrInfoEmitter.h" #include "AsmWriterEmitter.h" -#include "InstrSelectorEmitter.h" #include "DAGISelEmitter.h" +#include "SubtargetEmitter.h" #include #include #include @@ -34,8 +34,9 @@ PrintRecords, GenEmitter, GenRegisterEnums, GenRegister, GenRegisterHeader, - GenInstrEnums, GenInstrs, GenAsmWriter, GenInstrSelector, + GenInstrEnums, GenInstrs, GenAsmWriter, GenDAGISel, + GenSubtarget, PrintEnums, Parse }; @@ -59,10 +60,10 @@ "Generate instruction descriptions"), clEnumValN(GenAsmWriter, "gen-asm-writer", "Generate assembly writer"), - clEnumValN(GenInstrSelector, "gen-instr-selector", - "Generate an instruction selector"), clEnumValN(GenDAGISel, "gen-dag-isel", "Generate a DAG instruction selector"), + clEnumValN(GenSubtarget, "gen-subtarget", + "Generate subtarget enumerations"), clEnumValN(PrintEnums, "print-enums", "Print enum values for a class"), clEnumValN(Parse, "parse", @@ -466,12 +467,12 @@ AsmWriterEmitter(Records).run(*Out); break; - case GenInstrSelector: - InstrSelectorEmitter(Records).run(*Out); - break; case GenDAGISel: DAGISelEmitter(Records).run(*Out); break; + case GenSubtarget: + SubtargetEmitter(Records).run(*Out); + break; case PrintEnums: { std::vector Recs = Records.getAllDerivedDefinitions(Class); From bocchino at cs.uiuc.edu Wed Nov 16 12:34:05 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:34:05 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/win32/TableGen/.cvsignore TableGen.vcproj Message-ID: <200511161834.MAA21727@zion.cs.uiuc.edu> Changes in directory llvm/win32/TableGen: .cvsignore added (r1.1.4.2) TableGen.vcproj updated: 1.14 -> 1.14.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+23 -25) .cvsignore | 4 ++++ TableGen.vcproj | 44 +++++++++++++++++++------------------------- 2 files changed, 23 insertions(+), 25 deletions(-) Index: llvm/win32/TableGen/.cvsignore diff -c /dev/null llvm/win32/TableGen/.cvsignore:1.1.4.2 *** /dev/null Wed Nov 16 12:34:03 2005 --- llvm/win32/TableGen/.cvsignore Wed Nov 16 12:33:53 2005 *************** *** 0 **** --- 1,4 ---- + FileLexer.cpp + FileParser.cpp + FileParser.h + FileParser.output Index: llvm/win32/TableGen/TableGen.vcproj diff -u llvm/win32/TableGen/TableGen.vcproj:1.14 llvm/win32/TableGen/TableGen.vcproj:1.14.2.1 --- llvm/win32/TableGen/TableGen.vcproj:1.14 Fri Sep 9 21:00:02 2005 +++ llvm/win32/TableGen/TableGen.vcproj Wed Nov 16 12:33:53 2005 @@ -19,7 +19,7 @@ + CommandLine="..\doflex.cmd debug $(InputName) $(InputPath)" + Outputs="$(InputName).cpp"/> + CommandLine="..\doflex.cmd release $(InputName) $(InputPath)" + Outputs="$(InputName).cpp"/> + CommandLine="..\dobison.cmd File debug $(InputName) $(InputPath)" + Outputs="$(InputName).cpp;$(InputName).h;$(InputName).output"/> + CommandLine="..\dobison.cmd File release $(InputName) $(InputPath)" + Outputs="$(InputName).cpp;$(InputName).h;$(InputName).output"/> - - + + - - + + @@ -240,7 +234,7 @@ Name="Generated Files" Filter=""> + RelativePath="FileLexer.cpp"> + RelativePath="fileparser.cpp"> + RelativePath="fileparser.h"> From bocchino at cs.uiuc.edu Wed Nov 16 12:34:02 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:34:02 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/win32/CodeGen/CodeGen.vcproj Message-ID: <200511161834.MAA21711@zion.cs.uiuc.edu> Changes in directory llvm/win32/CodeGen: CodeGen.vcproj updated: 1.14 -> 1.14.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+0 -3) CodeGen.vcproj | 3 --- 1 files changed, 3 deletions(-) Index: llvm/win32/CodeGen/CodeGen.vcproj diff -u llvm/win32/CodeGen/CodeGen.vcproj:1.14 llvm/win32/CodeGen/CodeGen.vcproj:1.14.2.1 --- llvm/win32/CodeGen/CodeGen.vcproj:1.14 Sun Sep 25 14:04:43 2005 +++ llvm/win32/CodeGen/CodeGen.vcproj Wed Nov 16 12:33:50 2005 @@ -149,9 +149,6 @@ RelativePath="..\..\lib\CodeGen\PrologEpilogInserter.cpp"> - - Changes in directory llvm/win32/Target: Target.vcproj updated: 1.10 -> 1.10.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+3 -0) Target.vcproj | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/win32/Target/Target.vcproj diff -u llvm/win32/Target/Target.vcproj:1.10 llvm/win32/Target/Target.vcproj:1.10.2.1 --- llvm/win32/Target/Target.vcproj:1.10 Thu Sep 1 21:51:42 2005 +++ llvm/win32/Target/Target.vcproj Wed Nov 16 12:33:55 2005 @@ -157,6 +157,9 @@ RelativePath="..\..\include\llvm\Target\TargetInstrInfo.h"> + + Changes in directory llvm/win32/Configure: Configure.vcproj updated: 1.8 -> 1.8.4.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+22 -10) Configure.vcproj | 32 ++++++++++++++++++++++---------- 1 files changed, 22 insertions(+), 10 deletions(-) Index: llvm/win32/Configure/Configure.vcproj diff -u llvm/win32/Configure/Configure.vcproj:1.8 llvm/win32/Configure/Configure.vcproj:1.8.4.1 --- llvm/win32/Configure/Configure.vcproj:1.8 Tue Mar 15 23:49:58 2005 +++ llvm/win32/Configure/Configure.vcproj Wed Nov 16 12:33:52 2005 @@ -74,8 +74,24 @@ @@ -86,8 +102,7 @@ @@ -98,8 +113,7 @@ @@ -110,8 +124,7 @@ @@ -122,8 +135,7 @@ From bocchino at cs.uiuc.edu Wed Nov 16 12:34:09 2005 From: bocchino at cs.uiuc.edu (Robert Bocchino) Date: Wed, 16 Nov 2005 12:34:09 -0600 Subject: [llvm-commits] [vector_llvm] CVS: llvm/win32/analyze/analyze.vcproj Message-ID: <200511161834.MAA21748@zion.cs.uiuc.edu> Changes in directory llvm/win32/analyze: analyze.vcproj updated: 1.4 -> 1.4.4.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+0 -2) analyze.vcproj | 2 -- 1 files changed, 2 deletions(-) Index: llvm/win32/analyze/analyze.vcproj diff -u llvm/win32/analyze/analyze.vcproj:1.4 llvm/win32/analyze/analyze.vcproj:1.4.4.1 --- llvm/win32/analyze/analyze.vcproj:1.4 Sun Jan 30 11:54:12 2005 +++ llvm/win32/analyze/analyze.vcproj Wed Nov 16 12:33:58 2005 @@ -36,7 +36,6 @@ Name="VCCustomBuildTool"/> Changes in directory llvm/win32/x86: x86.vcproj updated: 1.14 -> 1.14.2.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+6 -0) x86.vcproj | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/win32/x86/x86.vcproj diff -u llvm/win32/x86/x86.vcproj:1.14 llvm/win32/x86/x86.vcproj:1.14.2.1 --- llvm/win32/x86/x86.vcproj:1.14 Fri Aug 19 08:51:22 2005 +++ llvm/win32/x86/x86.vcproj Wed Nov 16 12:33:59 2005 @@ -164,6 +164,9 @@ RelativePath="..\..\lib\Target\X86\X86IntelAsmPrinter.cpp"> + + + + Changes in directory llvm/win32/Transforms: Transforms.vcproj updated: 1.13 -> 1.13.4.1 --- Log message: Merged mainline into Vector LLVM branch --- Diffs of the changes: (+6 -34) Transforms.vcproj | 40 ++++++---------------------------------- 1 files changed, 6 insertions(+), 34 deletions(-) Index: llvm/win32/Transforms/Transforms.vcproj diff -u llvm/win32/Transforms/Transforms.vcproj:1.13 llvm/win32/Transforms/Transforms.vcproj:1.13.4.1 --- llvm/win32/Transforms/Transforms.vcproj:1.13 Mon Apr 25 21:57:49 2005 +++ llvm/win32/Transforms/Transforms.vcproj Wed Nov 16 12:33:56 2005 @@ -142,34 +142,6 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + Changes in directory llvm-test/MultiSource/Benchmarks/MallocBench: Makefile updated: 1.9 -> 1.10 --- Log message: who told them ints and pointers were interchangable --- Diffs of the changes: (+6 -0) Makefile | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm-test/MultiSource/Benchmarks/MallocBench/Makefile diff -u llvm-test/MultiSource/Benchmarks/MallocBench/Makefile:1.9 llvm-test/MultiSource/Benchmarks/MallocBench/Makefile:1.10 --- llvm-test/MultiSource/Benchmarks/MallocBench/Makefile:1.9 Thu Dec 2 11:13:22 2004 +++ llvm-test/MultiSource/Benchmarks/MallocBench/Makefile Wed Nov 16 14:35:50 2005 @@ -1,3 +1,9 @@ LEVEL = ../../.. PARALLEL_DIRS := cfrac espresso gs + +# cfrac mixes pointers and ints. Thus doesn't work on alpha. +ifeq ($(ARCH),Alpha) +PARALLEL_DIRS := $(filter-out cfrac, $(PARALLEL_DIRS)) +endif + include $(LEVEL)/Makefile.programs From alenhar2 at cs.uiuc.edu Wed Nov 16 15:16:13 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Wed, 16 Nov 2005 15:16:13 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaCodeEmitter.cpp Message-ID: <200511162116.PAA20662@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaCodeEmitter.cpp updated: 1.6 -> 1.7 --- Log message: who would have thought you would want to write into globals too --- Diffs of the changes: (+6 -0) AlphaCodeEmitter.cpp | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/lib/Target/Alpha/AlphaCodeEmitter.cpp diff -u llvm/lib/Target/Alpha/AlphaCodeEmitter.cpp:1.6 llvm/lib/Target/Alpha/AlphaCodeEmitter.cpp:1.7 --- llvm/lib/Target/Alpha/AlphaCodeEmitter.cpp:1.6 Thu Aug 4 10:32:36 2005 +++ llvm/lib/Target/Alpha/AlphaCodeEmitter.cpp Wed Nov 16 15:15:53 2005 @@ -193,6 +193,12 @@ case Alpha::LDSr: case Alpha::LDTr: case Alpha::LDAr: + case Alpha::STQr: + case Alpha::STLr: + case Alpha::STWr: + case Alpha::STBr: + case Alpha::STSr: + case Alpha::STTr: Reloc = Alpha::reloc_gprellow; break; case Alpha::LDAHr: From lattner at cs.uiuc.edu Wed Nov 16 16:59:31 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 16 Nov 2005 16:59:31 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp X86InstrInfo.td Message-ID: <200511162259.QAA22984@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.1 -> 1.2 X86InstrInfo.td updated: 1.135 -> 1.136 --- Log message: Add patterns for several simple instructions that take i32 immediates. Patch contributed by Evan Cheng! --- Diffs of the changes: (+36 -42) X86ISelDAGToDAG.cpp | 16 ------------- X86InstrInfo.td | 62 +++++++++++++++++++++++++++++----------------------- 2 files changed, 36 insertions(+), 42 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.1 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.2 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.1 Tue Nov 15 19:54:32 2005 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Wed Nov 16 16:59:19 2005 @@ -1,4 +1,4 @@ -//===-- X86ISelPattern.cpp - A DAG pattern matching inst selector for X86 -===// +//===- X86ISelDAGToDAG.cpp - A DAG pattern matching inst selector for X86 -===// // // The LLVM Compiler Infrastructure // @@ -103,20 +103,6 @@ switch (N->getOpcode()) { default: break; - case ISD::Constant: { - switch (OpVT) { - default: assert(0 && "Cannot use constants of this type!"); - case MVT::i1: - case MVT::i8: Opc = X86::MOV8ri; break; - case MVT::i16: Opc = X86::MOV16ri; break; - case MVT::i32: Opc = X86::MOV32ri; break; - } - unsigned CVal = cast(N)->getValue(); - SDOperand Op1 = CurDAG->getTargetConstant(CVal, OpVT); - CurDAG->SelectNodeTo(N, Opc, OpVT, Op1); - return Op; - } - case ISD::RET: { SDOperand Chain = Select(N->getOperand(0)); // Token chain. switch (N->getNumOperands()) { Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.135 llvm/lib/Target/X86/X86InstrInfo.td:1.136 --- llvm/lib/Target/X86/X86InstrInfo.td:1.135 Fri Oct 14 17:06:00 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Wed Nov 16 16:59:19 2005 @@ -135,8 +135,10 @@ : X86Inst; class Ii16 o, Format f, dag ops, string asm> : X86Inst; -class Ii32 o, Format f, dag ops, string asm> - : X86Inst; +class Ii32 o, Format f, dag ops, string asm, list pattern> + : X86Inst { + let Pattern = pattern; +} //===----------------------------------------------------------------------===// // Instruction list... @@ -213,7 +215,7 @@ // within a function. let isTerminator = 1, isTwoAddress = 1 in def ADJSTACKPTRri : Ii32<0x81, MRM0r, (ops R32:$dst, R32:$src1, i32imm:$src2), - "add{l} {$src2, $dst|$dst, $src2}">; + "add{l} {$src2, $dst|$dst, $src2}", []>; //===----------------------------------------------------------------------===// // Miscellaneous Instructions... @@ -324,13 +326,13 @@ def MOV16ri : Ii16<0xB8, AddRegFrm, (ops R16:$dst, i16imm:$src), "mov{w} {$src, $dst|$dst, $src}">, OpSize; def MOV32ri : Ii32<0xB8, AddRegFrm, (ops R32:$dst, i32imm:$src), - "mov{l} {$src, $dst|$dst, $src}">; + "mov{l} {$src, $dst|$dst, $src}", [(set R32:$dst, imm:$src)]>; def MOV8mi : Ii8 <0xC6, MRM0m, (ops i8mem :$dst, i8imm :$src), "mov{b} {$src, $dst|$dst, $src}">; def MOV16mi : Ii16<0xC7, MRM0m, (ops i16mem:$dst, i16imm:$src), "mov{w} {$src, $dst|$dst, $src}">, OpSize; def MOV32mi : Ii32<0xC7, MRM0m, (ops i32mem:$dst, i32imm:$src), - "mov{l} {$src, $dst|$dst, $src}">; + "mov{l} {$src, $dst|$dst, $src}", []>; def MOV8rm : I<0x8A, MRMSrcMem, (ops R8 :$dst, i8mem :$src), "mov{b} {$src, $dst|$dst, $src}">; @@ -677,7 +679,8 @@ "and{w} {$src2, $dst|$dst, $src2}">, OpSize; def AND32ri : Ii32<0x81, MRM4r, (ops R32:$dst, R32:$src1, i32imm:$src2), - "and{l} {$src2, $dst|$dst, $src2}">; + "and{l} {$src2, $dst|$dst, $src2}", + [(set R32:$dst, (and R32:$src1, imm:$src2))]>; def AND16ri8 : Ii8<0x83, MRM4r, (ops R16:$dst, R16:$src1, i8imm:$src2), "and{w} {$src2, $dst|$dst, $src2}" >, OpSize; @@ -703,7 +706,7 @@ "and{w} {$src, $dst|$dst, $src}">, OpSize; def AND32mi : Ii32<0x81, MRM4m, (ops i32mem:$dst, i32imm:$src), - "and{l} {$src, $dst|$dst, $src}">; + "and{l} {$src, $dst|$dst, $src}", []>; def AND16mi8 : Ii8<0x83, MRM4m, (ops i16mem:$dst, i8imm :$src), "and{w} {$src, $dst|$dst, $src}">, OpSize; @@ -733,7 +736,8 @@ def OR16ri : Ii16<0x81, MRM1r, (ops R16:$dst, R16:$src1, i16imm:$src2), "or{w} {$src2, $dst|$dst, $src2}">, OpSize; def OR32ri : Ii32<0x81, MRM1r, (ops R32:$dst, R32:$src1, i32imm:$src2), - "or{l} {$src2, $dst|$dst, $src2}">; + "or{l} {$src2, $dst|$dst, $src2}", + [(set R32:$dst, (or R32:$src1, imm:$src2))]>; def OR16ri8 : Ii8<0x83, MRM1r, (ops R8 :$dst, R8 :$src1, i8imm:$src2), "or{w} {$src2, $dst|$dst, $src2}">, OpSize; @@ -751,7 +755,7 @@ def OR16mi : Ii16<0x81, MRM1m, (ops i16mem:$dst, i16imm:$src), "or{w} {$src, $dst|$dst, $src}">, OpSize; def OR32mi : Ii32<0x81, MRM1m, (ops i32mem:$dst, i32imm:$src), - "or{l} {$src, $dst|$dst, $src}">; + "or{l} {$src, $dst|$dst, $src}", []>; def OR16mi8 : Ii8<0x83, MRM1m, (ops i16mem:$dst, i8imm:$src), "or{w} {$src, $dst|$dst, $src}">, OpSize; def OR32mi8 : Ii8<0x83, MRM1m, (ops i32mem:$dst, i8imm:$src), @@ -789,7 +793,8 @@ "xor{w} {$src2, $dst|$dst, $src2}">, OpSize; def XOR32ri : Ii32<0x81, MRM6r, (ops R32:$dst, R32:$src1, i32imm:$src2), - "xor{l} {$src2, $dst|$dst, $src2}">; + "xor{l} {$src2, $dst|$dst, $src2}", + [(set R32:$dst, (xor R32:$src1, imm:$src2))]>; def XOR16ri8 : Ii8<0x83, MRM6r, (ops R16:$dst, R16:$src1, i8imm:$src2), "xor{w} {$src2, $dst|$dst, $src2}">, OpSize; @@ -814,7 +819,7 @@ "xor{w} {$src, $dst|$dst, $src}">, OpSize; def XOR32mi : Ii32<0x81, MRM6m, (ops i32mem:$dst, i32imm:$src), - "xor{l} {$src, $dst|$dst, $src}">; + "xor{l} {$src, $dst|$dst, $src}", []>; def XOR16mi8 : Ii8<0x83, MRM6m, (ops i16mem:$dst, i8imm :$src), "xor{w} {$src, $dst|$dst, $src}">, OpSize; @@ -1062,7 +1067,8 @@ def ADD16ri : Ii16<0x81, MRM0r, (ops R16:$dst, R16:$src1, i16imm:$src2), "add{w} {$src2, $dst|$dst, $src2}">, OpSize; def ADD32ri : Ii32<0x81, MRM0r, (ops R32:$dst, R32:$src1, i32imm:$src2), - "add{l} {$src2, $dst|$dst, $src2}">; + "add{l} {$src2, $dst|$dst, $src2}", + [(set R32:$dst, (add R32:$src1, imm:$src2))]>; } def ADD16ri8 : Ii8<0x83, MRM0r, (ops R16:$dst, R16:$src1, i8imm:$src2), @@ -1082,7 +1088,7 @@ def ADD16mi : Ii16<0x81, MRM0m, (ops i16mem:$dst, i16imm:$src2), "add{w} {$src2, $dst|$dst, $src2}">, OpSize; def ADD32mi : Ii32<0x81, MRM0m, (ops i32mem:$dst, i32imm:$src2), - "add{l} {$src2, $dst|$dst, $src2}">; + "add{l} {$src2, $dst|$dst, $src2}", []>; def ADD16mi8 : Ii8<0x83, MRM0m, (ops i16mem:$dst, i8imm :$src2), "add{w} {$src2, $dst|$dst, $src2}">, OpSize; def ADD32mi8 : Ii8<0x83, MRM0m, (ops i32mem:$dst, i8imm :$src2), @@ -1096,7 +1102,7 @@ def ADC32rm : I<0x13, MRMSrcMem , (ops R32:$dst, R32:$src1, i32mem:$src2), "adc{l} {$src2, $dst|$dst, $src2}">; def ADC32ri : Ii32<0x81, MRM2r, (ops R32:$dst, R32:$src1, i32imm:$src2), - "adc{l} {$src2, $dst|$dst, $src2}">; + "adc{l} {$src2, $dst|$dst, $src2}", []>; def ADC32ri8 : Ii8<0x83, MRM2r, (ops R32:$dst, R32:$src1, i8imm:$src2), "adc{l} {$src2, $dst|$dst, $src2}">; @@ -1104,7 +1110,7 @@ def ADC32mr : I<0x11, MRMDestMem, (ops i32mem:$dst, R32:$src2), "adc{l} {$src2, $dst|$dst, $src2}">; def ADC32mi : Ii32<0x81, MRM2m, (ops i32mem:$dst, i32imm:$src2), - "adc{l} {$src2, $dst|$dst, $src2}">; + "adc{l} {$src2, $dst|$dst, $src2}", []>; def ADC32mi8 : Ii8<0x83, MRM2m, (ops i32mem:$dst, i8imm :$src2), "adc{l} {$src2, $dst|$dst, $src2}">; } @@ -1127,7 +1133,8 @@ def SUB16ri : Ii16<0x81, MRM5r, (ops R16:$dst, R16:$src1, i16imm:$src2), "sub{w} {$src2, $dst|$dst, $src2}">, OpSize; def SUB32ri : Ii32<0x81, MRM5r, (ops R32:$dst, R32:$src1, i32imm:$src2), - "sub{l} {$src2, $dst|$dst, $src2}">; + "sub{l} {$src2, $dst|$dst, $src2}", + [(set R32:$dst, (sub R32:$src1, imm:$src2))]>; def SUB16ri8 : Ii8<0x83, MRM5r, (ops R16:$dst, R16:$src1, i8imm:$src2), "sub{w} {$src2, $dst|$dst, $src2}">, OpSize; def SUB32ri8 : Ii8<0x83, MRM5r, (ops R32:$dst, R32:$src1, i8imm:$src2), @@ -1144,7 +1151,7 @@ def SUB16mi : Ii16<0x81, MRM5m, (ops i16mem:$dst, i16imm:$src2), "sub{w} {$src2, $dst|$dst, $src2}">, OpSize; def SUB32mi : Ii32<0x81, MRM5m, (ops i32mem:$dst, i32imm:$src2), - "sub{l} {$src2, $dst|$dst, $src2}">; + "sub{l} {$src2, $dst|$dst, $src2}", []>; def SUB16mi8 : Ii8<0x83, MRM5m, (ops i16mem:$dst, i8imm :$src2), "sub{w} {$src2, $dst|$dst, $src2}">, OpSize; def SUB32mi8 : Ii8<0x83, MRM5m, (ops i32mem:$dst, i8imm :$src2), @@ -1158,11 +1165,11 @@ def SBB32mr : I<0x19, MRMDestMem, (ops i32mem:$dst, R32:$src2), "sbb{l} {$src2, $dst|$dst, $src2}">; def SBB8mi : Ii32<0x80, MRM3m, (ops i8mem:$dst, i8imm:$src2), - "sbb{b} {$src2, $dst|$dst, $src2}">; + "sbb{b} {$src2, $dst|$dst, $src2}", []>; def SBB16mi : Ii32<0x81, MRM3m, (ops i16mem:$dst, i16imm:$src2), - "sbb{w} {$src2, $dst|$dst, $src2}">, OpSize; + "sbb{w} {$src2, $dst|$dst, $src2}", []>, OpSize; def SBB32mi : Ii32<0x81, MRM3m, (ops i32mem:$dst, i32imm:$src2), - "sbb{l} {$src2, $dst|$dst, $src2}">; + "sbb{l} {$src2, $dst|$dst, $src2}", []>; def SBB16mi8 : Ii8<0x83, MRM3m, (ops i16mem:$dst, i8imm :$src2), "sbb{w} {$src2, $dst|$dst, $src2}">, OpSize; def SBB32mi8 : Ii8<0x83, MRM3m, (ops i32mem:$dst, i8imm :$src2), @@ -1176,7 +1183,7 @@ def SBB32rm : I<0x1B, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2), "sbb{l} {$src2, $dst|$dst, $src2}">; def SBB32ri : Ii32<0x81, MRM3r, (ops R32:$dst, R32:$src1, i32imm:$src2), - "sbb{l} {$src2, $dst|$dst, $src2}">; + "sbb{l} {$src2, $dst|$dst, $src2}", []>; def SBB16ri8 : Ii8<0x83, MRM3r, (ops R16:$dst, R16:$src1, i8imm:$src2), "sbb{w} {$src2, $dst|$dst, $src2}">, OpSize; @@ -1203,7 +1210,8 @@ OpSize; def IMUL32rri : Ii32<0x69, MRMSrcReg, // R32 = R32*I32 (ops R32:$dst, R32:$src1, i32imm:$src2), - "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}">; + "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}", + [(set R32:$dst, (mul R32:$src1, imm:$src2))]>; def IMUL16rri8 : Ii8<0x6B, MRMSrcReg, // R16 = R16*I8 (ops R16:$dst, R16:$src1, i8imm:$src2), "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}">, OpSize; @@ -1216,7 +1224,7 @@ "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}">, OpSize; def IMUL32rmi : Ii32<0x69, MRMSrcMem, // R32 = [mem32]*I32 (ops R32:$dst, i32mem:$src1, i32imm:$src2), - "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}">; + "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}", []>; def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem, // R16 = [mem16]*I8 (ops R32:$dst, i16mem:$src1, i8imm :$src2), "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}">, OpSize; @@ -1256,7 +1264,7 @@ "test{w} {$src2, $src1|$src1, $src2}">, OpSize; def TEST32ri : Ii32<0xF7, MRM0r, // flags = R32 & imm32 (ops R32:$src1, i32imm:$src2), - "test{l} {$src2, $src1|$src1, $src2}">; + "test{l} {$src2, $src1|$src1, $src2}", []>; def TEST8mi : Ii8 <0xF6, MRM0m, // flags = [mem8] & imm8 (ops i32mem:$src1, i8imm:$src2), "test{b} {$src2, $src1|$src1, $src2}">; @@ -1265,7 +1273,7 @@ "test{w} {$src2, $src1|$src1, $src2}">, OpSize; def TEST32mi : Ii32<0xF7, MRM0m, // flags = [mem32] & imm32 (ops i32mem:$src1, i32imm:$src2), - "test{l} {$src2, $src1|$src1, $src2}">; + "test{l} {$src2, $src1|$src1, $src2}", []>; @@ -1366,7 +1374,7 @@ "cmp{w} {$src2, $src1|$src1, $src2}">, OpSize; def CMP32ri : Ii32<0x81, MRM7r, (ops R32:$src1, i32imm:$src2), - "cmp{l} {$src2, $src1|$src1, $src2}">; + "cmp{l} {$src2, $src1|$src1, $src2}", []>; def CMP8mi : Ii8 <0x80, MRM7m, (ops i8mem :$src1, i8imm :$src2), "cmp{b} {$src2, $src1|$src1, $src2}">; @@ -1375,7 +1383,7 @@ "cmp{w} {$src2, $src1|$src1, $src2}">, OpSize; def CMP32mi : Ii32<0x81, MRM7m, (ops i32mem:$src1, i32imm:$src2), - "cmp{l} {$src2, $src1|$src1, $src2}">; + "cmp{l} {$src2, $src1|$src1, $src2}", []>; // Sign/Zero extenders def MOVSX16rr8 : I<0xBE, MRMSrcReg, (ops R16:$dst, R8 :$src), From lattner at cs.uiuc.edu Wed Nov 16 17:15:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 16 Nov 2005 17:15:05 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200511162315.RAA23180@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.73 -> 1.74 --- Log message: fix a tblgen bug that Evan ran into, where we would lose the '$src' name on patterns like "(set R32:$dst, (i32 imm:$src))" --- Diffs of the changes: (+4 -4) DAGISelEmitter.cpp | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.73 llvm/utils/TableGen/DAGISelEmitter.cpp:1.74 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.73 Wed Nov 2 23:46:11 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Wed Nov 16 17:14:54 2005 @@ -631,9 +631,7 @@ if (R->isSubClassOf("SDNode") || R->isSubClassOf("PatFrag")) { Dag->setArg(0, new DagInit(R, std::vector >())); - TreePatternNode *TPN = ParseTreePattern(Dag); - TPN->setName(Dag->getArgName(0)); - return TPN; + return ParseTreePattern(Dag); } New = new TreePatternNode(DI); @@ -651,6 +649,7 @@ // Apply the type cast. New->UpdateNodeType(getValueType(Operator), *this); + New->setName(Dag->getArgName(0)); return New; } @@ -672,7 +671,8 @@ Init *Arg = Dag->getArg(i); if (DagInit *DI = dynamic_cast(Arg)) { Children.push_back(ParseTreePattern(DI)); - Children.back()->setName(Dag->getArgName(i)); + if (Children.back()->getName().empty()) + Children.back()->setName(Dag->getArgName(i)); } else if (DefInit *DefI = dynamic_cast(Arg)) { Record *R = DefI->getDef(); // Direct reference to a leaf DagNode or PatFrag? Turn it into a From lattner at cs.uiuc.edu Wed Nov 16 20:02:07 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 16 Nov 2005 20:02:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200511170202.UAA24217@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.136 -> 1.137 --- Log message: Add patterns for some 16-bit immediate instructions, patch contributed by Evan Cheng. --- Diffs of the changes: (+37 -28) X86InstrInfo.td | 65 +++++++++++++++++++++++++++++++------------------------- 1 files changed, 37 insertions(+), 28 deletions(-) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.136 llvm/lib/Target/X86/X86InstrInfo.td:1.137 --- llvm/lib/Target/X86/X86InstrInfo.td:1.136 Wed Nov 16 16:59:19 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Wed Nov 16 20:01:55 2005 @@ -133,8 +133,10 @@ : X86Inst; class Ii8 o, Format f, dag ops, string asm> : X86Inst; -class Ii16 o, Format f, dag ops, string asm> - : X86Inst; +class Ii16 o, Format f, dag ops, string asm, list pattern> + : X86Inst { + let Pattern = pattern; +} class Ii32 o, Format f, dag ops, string asm, list pattern> : X86Inst { let Pattern = pattern; @@ -164,7 +166,7 @@ let isTerminator = 1, isReturn = 1, isBarrier = 1 in def RET : I<0xC3, RawFrm, (ops), "ret">; let isTerminator = 1, isReturn = 1, isBarrier = 1 in - def RETI : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt">; + def RETI : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt", []>; // All branches are RawFrm, Void, Branch, and Terminators let isBranch = 1, isTerminator = 1 in @@ -292,11 +294,11 @@ "in{l} {%dx, %eax|%EAX, %DX}">, Imp<[DX],[EAX]>; def IN8ri : Ii16<0xE4, RawFrm, (ops i16imm:$port), - "in{b} {$port, %al|%AL, $port}">, Imp<[], [AL]>; + "in{b} {$port, %al|%AL, $port}", []>, Imp<[], [AL]>; def IN16ri : Ii16<0xE5, RawFrm, (ops i16imm:$port), - "in{w} {$port, %ax|%AX, $port}">, Imp<[], [AX]>, OpSize; + "in{w} {$port, %ax|%AX, $port}", []>, Imp<[], [AX]>, OpSize; def IN32ri : Ii16<0xE5, RawFrm, (ops i16imm:$port), - "in{l} {$port, %eax|%EAX, $port}">, Imp<[],[EAX]>; + "in{l} {$port, %eax|%EAX, $port}", []>, Imp<[],[EAX]>; def OUT8rr : I<0xEE, RawFrm, (ops), "out{b} {%al, %dx|%DX, %AL}">, Imp<[DX, AL], []>; @@ -306,11 +308,11 @@ "out{l} {%eax, %dx|%DX, %EAX}">, Imp<[DX, EAX], []>; def OUT8ir : Ii16<0xE6, RawFrm, (ops i16imm:$port), - "out{b} {%al, $port|$port, %AL}">, Imp<[AL], []>; + "out{b} {%al, $port|$port, %AL}", []>, Imp<[AL], []>; def OUT16ir : Ii16<0xE7, RawFrm, (ops i16imm:$port), - "out{w} {%ax, $port|$port, %AX}">, Imp<[AX], []>, OpSize; + "out{w} {%ax, $port|$port, %AX}", []>, Imp<[AX], []>, OpSize; def OUT32ir : Ii16<0xE7, RawFrm, (ops i16imm:$port), - "out{l} {%eax, $port|$port, %EAX}">, Imp<[EAX], []>; + "out{l} {%eax, $port|$port, %EAX}", []>, Imp<[EAX], []>; //===----------------------------------------------------------------------===// // Move Instructions... @@ -324,13 +326,14 @@ def MOV8ri : Ii8 <0xB0, AddRegFrm, (ops R8 :$dst, i8imm :$src), "mov{b} {$src, $dst|$dst, $src}">; def MOV16ri : Ii16<0xB8, AddRegFrm, (ops R16:$dst, i16imm:$src), - "mov{w} {$src, $dst|$dst, $src}">, OpSize; + "mov{w} {$src, $dst|$dst, $src}", [(set R16:$dst, imm:$src)]>, + OpSize; def MOV32ri : Ii32<0xB8, AddRegFrm, (ops R32:$dst, i32imm:$src), "mov{l} {$src, $dst|$dst, $src}", [(set R32:$dst, imm:$src)]>; def MOV8mi : Ii8 <0xC6, MRM0m, (ops i8mem :$dst, i8imm :$src), "mov{b} {$src, $dst|$dst, $src}">; def MOV16mi : Ii16<0xC7, MRM0m, (ops i16mem:$dst, i16imm:$src), - "mov{w} {$src, $dst|$dst, $src}">, OpSize; + "mov{w} {$src, $dst|$dst, $src}", []>, OpSize; def MOV32mi : Ii32<0xC7, MRM0m, (ops i32mem:$dst, i32imm:$src), "mov{l} {$src, $dst|$dst, $src}", []>; @@ -676,7 +679,8 @@ "and{b} {$src2, $dst|$dst, $src2}">; def AND16ri : Ii16<0x81, MRM4r, (ops R16:$dst, R16:$src1, i16imm:$src2), - "and{w} {$src2, $dst|$dst, $src2}">, OpSize; + "and{w} {$src2, $dst|$dst, $src2}", + [(set R16:$dst, (and R16:$src1, imm:$src2))]>, OpSize; def AND32ri : Ii32<0x81, MRM4r, (ops R32:$dst, R32:$src1, i32imm:$src2), "and{l} {$src2, $dst|$dst, $src2}", @@ -703,7 +707,7 @@ "and{b} {$src, $dst|$dst, $src}">; def AND16mi : Ii16<0x81, MRM4m, (ops i16mem:$dst, i16imm:$src), - "and{w} {$src, $dst|$dst, $src}">, OpSize; + "and{w} {$src, $dst|$dst, $src}", []>, OpSize; def AND32mi : Ii32<0x81, MRM4m, (ops i32mem:$dst, i32imm:$src), "and{l} {$src, $dst|$dst, $src}", []>; @@ -734,7 +738,8 @@ def OR8ri : Ii8 <0x80, MRM1r, (ops R8 :$dst, R8 :$src1, i8imm:$src2), "or{b} {$src2, $dst|$dst, $src2}">; def OR16ri : Ii16<0x81, MRM1r, (ops R16:$dst, R16:$src1, i16imm:$src2), - "or{w} {$src2, $dst|$dst, $src2}">, OpSize; + "or{w} {$src2, $dst|$dst, $src2}", + [(set R16:$dst, (or R16:$src1, imm:$src2))]>, OpSize; def OR32ri : Ii32<0x81, MRM1r, (ops R32:$dst, R32:$src1, i32imm:$src2), "or{l} {$src2, $dst|$dst, $src2}", [(set R32:$dst, (or R32:$src1, imm:$src2))]>; @@ -753,7 +758,7 @@ def OR8mi : Ii8<0x80, MRM1m, (ops i8mem :$dst, i8imm:$src), "or{b} {$src, $dst|$dst, $src}">; def OR16mi : Ii16<0x81, MRM1m, (ops i16mem:$dst, i16imm:$src), - "or{w} {$src, $dst|$dst, $src}">, OpSize; + "or{w} {$src, $dst|$dst, $src}", []>, OpSize; def OR32mi : Ii32<0x81, MRM1m, (ops i32mem:$dst, i32imm:$src), "or{l} {$src, $dst|$dst, $src}", []>; def OR16mi8 : Ii8<0x83, MRM1m, (ops i16mem:$dst, i8imm:$src), @@ -790,7 +795,8 @@ "xor{b} {$src2, $dst|$dst, $src2}">; def XOR16ri : Ii16<0x81, MRM6r, (ops R16:$dst, R16:$src1, i16imm:$src2), - "xor{w} {$src2, $dst|$dst, $src2}">, OpSize; + "xor{w} {$src2, $dst|$dst, $src2}", + [(set R16:$dst, (xor R16:$src1, imm:$src2))]>, OpSize; def XOR32ri : Ii32<0x81, MRM6r, (ops R32:$dst, R32:$src1, i32imm:$src2), "xor{l} {$src2, $dst|$dst, $src2}", @@ -816,7 +822,7 @@ "xor{b} {$src, $dst|$dst, $src}">; def XOR16mi : Ii16<0x81, MRM6m, (ops i16mem:$dst, i16imm:$src), - "xor{w} {$src, $dst|$dst, $src}">, OpSize; + "xor{w} {$src, $dst|$dst, $src}", []>, OpSize; def XOR32mi : Ii32<0x81, MRM6m, (ops i32mem:$dst, i32imm:$src), "xor{l} {$src, $dst|$dst, $src}", []>; @@ -1065,7 +1071,8 @@ let isConvertibleToThreeAddress = 1 in { // Can transform into LEA. def ADD16ri : Ii16<0x81, MRM0r, (ops R16:$dst, R16:$src1, i16imm:$src2), - "add{w} {$src2, $dst|$dst, $src2}">, OpSize; + "add{w} {$src2, $dst|$dst, $src2}", + [(set R16:$dst, (add R16:$src1, imm:$src2))]>, OpSize; def ADD32ri : Ii32<0x81, MRM0r, (ops R32:$dst, R32:$src1, i32imm:$src2), "add{l} {$src2, $dst|$dst, $src2}", [(set R32:$dst, (add R32:$src1, imm:$src2))]>; @@ -1086,7 +1093,7 @@ def ADD8mi : Ii8<0x80, MRM0m, (ops i8mem :$dst, i8imm :$src2), "add{b} {$src2, $dst|$dst, $src2}">; def ADD16mi : Ii16<0x81, MRM0m, (ops i16mem:$dst, i16imm:$src2), - "add{w} {$src2, $dst|$dst, $src2}">, OpSize; + "add{w} {$src2, $dst|$dst, $src2}", []>, OpSize; def ADD32mi : Ii32<0x81, MRM0m, (ops i32mem:$dst, i32imm:$src2), "add{l} {$src2, $dst|$dst, $src2}", []>; def ADD16mi8 : Ii8<0x83, MRM0m, (ops i16mem:$dst, i8imm :$src2), @@ -1131,7 +1138,8 @@ def SUB8ri : Ii8 <0x80, MRM5r, (ops R8:$dst, R8:$src1, i8imm:$src2), "sub{b} {$src2, $dst|$dst, $src2}">; def SUB16ri : Ii16<0x81, MRM5r, (ops R16:$dst, R16:$src1, i16imm:$src2), - "sub{w} {$src2, $dst|$dst, $src2}">, OpSize; + "sub{w} {$src2, $dst|$dst, $src2}", + [(set R16:$dst, (sub R16:$src1, imm:$src2))]>, OpSize; def SUB32ri : Ii32<0x81, MRM5r, (ops R32:$dst, R32:$src1, i32imm:$src2), "sub{l} {$src2, $dst|$dst, $src2}", [(set R32:$dst, (sub R32:$src1, imm:$src2))]>; @@ -1149,7 +1157,7 @@ def SUB8mi : Ii8<0x80, MRM5m, (ops i8mem :$dst, i8imm:$src2), "sub{b} {$src2, $dst|$dst, $src2}">; def SUB16mi : Ii16<0x81, MRM5m, (ops i16mem:$dst, i16imm:$src2), - "sub{w} {$src2, $dst|$dst, $src2}">, OpSize; + "sub{w} {$src2, $dst|$dst, $src2}", []>, OpSize; def SUB32mi : Ii32<0x81, MRM5m, (ops i32mem:$dst, i32imm:$src2), "sub{l} {$src2, $dst|$dst, $src2}", []>; def SUB16mi8 : Ii8<0x83, MRM5m, (ops i16mem:$dst, i8imm :$src2), @@ -1178,7 +1186,7 @@ def SBB8ri : Ii8<0x80, MRM3r, (ops R8:$dst, R8:$src1, i8imm:$src2), "sbb{b} {$src2, $dst|$dst, $src2}">; def SBB16ri : Ii16<0x81, MRM3r, (ops R16:$dst, R16:$src1, i16imm:$src2), - "sbb{w} {$src2, $dst|$dst, $src2}">, OpSize; + "sbb{w} {$src2, $dst|$dst, $src2}", []>, OpSize; def SBB32rm : I<0x1B, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2), "sbb{l} {$src2, $dst|$dst, $src2}">; @@ -1206,7 +1214,8 @@ // Suprisingly enough, these are not two address instructions! def IMUL16rri : Ii16<0x69, MRMSrcReg, // R16 = R16*I16 (ops R16:$dst, R16:$src1, i16imm:$src2), - "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}">, + "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}", + [(set R16:$dst, (mul R16:$src1, imm:$src2))]>, OpSize; def IMUL32rri : Ii32<0x69, MRMSrcReg, // R32 = R32*I32 (ops R32:$dst, R32:$src1, i32imm:$src2), @@ -1221,7 +1230,7 @@ def IMUL16rmi : Ii16<0x69, MRMSrcMem, // R16 = [mem16]*I16 (ops R32:$dst, i16mem:$src1, i16imm:$src2), - "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}">, OpSize; + "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}", []>, OpSize; def IMUL32rmi : Ii32<0x69, MRMSrcMem, // R32 = [mem32]*I32 (ops R32:$dst, i32mem:$src1, i32imm:$src2), "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}", []>; @@ -1261,7 +1270,7 @@ "test{b} {$src2, $src1|$src1, $src2}">; def TEST16ri : Ii16<0xF7, MRM0r, // flags = R16 & imm16 (ops R16:$src1, i16imm:$src2), - "test{w} {$src2, $src1|$src1, $src2}">, OpSize; + "test{w} {$src2, $src1|$src1, $src2}", []>, OpSize; def TEST32ri : Ii32<0xF7, MRM0r, // flags = R32 & imm32 (ops R32:$src1, i32imm:$src2), "test{l} {$src2, $src1|$src1, $src2}", []>; @@ -1270,7 +1279,7 @@ "test{b} {$src2, $src1|$src1, $src2}">; def TEST16mi : Ii16<0xF7, MRM0m, // flags = [mem16] & imm16 (ops i16mem:$src1, i16imm:$src2), - "test{w} {$src2, $src1|$src1, $src2}">, OpSize; + "test{w} {$src2, $src1|$src1, $src2}", []>, OpSize; def TEST32mi : Ii32<0xF7, MRM0m, // flags = [mem32] & imm32 (ops i32mem:$src1, i32imm:$src2), "test{l} {$src2, $src1|$src1, $src2}", []>; @@ -1371,7 +1380,7 @@ "cmp{b} {$src2, $src1|$src1, $src2}">; def CMP16ri : Ii16<0x81, MRM7r, (ops R16:$src1, i16imm:$src2), - "cmp{w} {$src2, $src1|$src1, $src2}">, OpSize; + "cmp{w} {$src2, $src1|$src1, $src2}", []>, OpSize; def CMP32ri : Ii32<0x81, MRM7r, (ops R32:$src1, i32imm:$src2), "cmp{l} {$src2, $src1|$src1, $src2}", []>; @@ -1380,7 +1389,7 @@ "cmp{b} {$src2, $src1|$src1, $src2}">; def CMP16mi : Ii16<0x81, MRM7m, (ops i16mem:$src1, i16imm:$src2), - "cmp{w} {$src2, $src1|$src1, $src2}">, OpSize; + "cmp{w} {$src2, $src1|$src1, $src2}", []>, OpSize; def CMP32mi : Ii32<0x81, MRM7m, (ops i32mem:$src1, i32imm:$src2), "cmp{l} {$src2, $src1|$src1, $src2}", []>; From lattner at cs.uiuc.edu Wed Nov 16 23:52:36 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 16 Nov 2005 23:52:36 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200511170552.XAA24982@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.207 -> 1.208 --- Log message: Teach legalize about targetglobaladdress --- Diffs of the changes: (+1 -0) LegalizeDAG.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.207 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.208 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.207 Fri Nov 11 10:46:18 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Nov 16 23:52:24 2005 @@ -525,6 +525,7 @@ case ISD::Register: case ISD::TargetConstant: case ISD::GlobalAddress: + case ISD::TargetGlobalAddress: case ISD::ExternalSymbol: case ISD::ConstantPool: // Nothing to do. case ISD::BasicBlock: From lattner at cs.uiuc.edu Wed Nov 16 23:56:25 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 16 Nov 2005 23:56:25 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp PPCISelLowering.cpp Message-ID: <200511170556.XAA25048@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.126 -> 1.127 PPCISelLowering.cpp updated: 1.39 -> 1.40 --- Log message: When lowering direct calls, lower them to use a targetglobaladress directly instead of a globaladdress. This has no effect on the generated code at all. --- Diffs of the changes: (+6 -2) PPCISelDAGToDAG.cpp | 3 +-- PPCISelLowering.cpp | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.126 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.127 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.126 Tue Nov 15 18:48:01 2005 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Wed Nov 16 23:56:14 2005 @@ -753,8 +753,7 @@ if (GlobalAddressSDNode *GASD = dyn_cast(N->getOperand(1))) { CallOpcode = PPC::BL; - CallOperands.push_back(CurDAG->getTargetGlobalAddress(GASD->getGlobal(), - MVT::i32)); + CallOperands.push_back(N->getOperand(1)); } else if (ExternalSymbolSDNode *ESSDN = dyn_cast(N->getOperand(1))) { CallOpcode = PPC::BL; Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.39 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.40 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.39 Wed Oct 26 13:01:11 2005 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Wed Nov 16 23:56:14 2005 @@ -691,6 +691,11 @@ RetVals.push_back(ActualRetTyVT); RetVals.push_back(MVT::Other); + // If the callee is a GlobalAddress node (quite common, every direct call is) + // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. + if (GlobalAddressSDNode *G = dyn_cast(Callee)) + Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i32); + SDOperand TheCall = SDOperand(DAG.getCall(RetVals, Chain, Callee, args_to_use), 0); Chain = TheCall.getValue(RetTyVT != MVT::isVoid); From lattner at cs.uiuc.edu Thu Nov 17 00:41:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 17 Nov 2005 00:41:55 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200511170641.AAA25270@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.208 -> 1.209 --- Log message: Allow targets to custom legalize leaf nodes like GlobalAddress. --- Diffs of the changes: (+13 -1) LegalizeDAG.cpp | 14 +++++++++++++- 1 files changed, 13 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.208 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.209 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.208 Wed Nov 16 23:52:24 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Nov 17 00:41:44 2005 @@ -532,7 +532,19 @@ case ISD::CONDCODE: case ISD::VALUETYPE: case ISD::SRCVALUE: - assert(isTypeLegal(Node->getValueType(0)) && "This must be legal!"); + switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Custom: { + SDOperand Tmp = TLI.LowerOperation(Op, DAG); + if (Tmp.Val) { + Result = LegalizeOp(Tmp); + break; + } + } // FALLTHROUGH if the target doesn't want to lower this op after all. + case TargetLowering::Legal: + assert(isTypeLegal(Node->getValueType(0)) && "This must be legal!"); + break; + } break; case ISD::AssertSext: case ISD::AssertZext: From lattner at cs.uiuc.edu Thu Nov 17 01:04:55 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 17 Nov 2005 01:04:55 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCInstrInfo.td Message-ID: <200511170704.BAA25436@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCInstrInfo.td updated: 1.139 -> 1.140 --- Log message: LI could theoretically be used for the lo-part of a global address, just like lis can be used for the high part. --- Diffs of the changes: (+1 -1) PPCInstrInfo.td | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.139 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.140 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.139 Tue Nov 15 18:48:01 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Thu Nov 17 01:04:43 2005 @@ -260,7 +260,7 @@ def SUBFIC : DForm_2< 8, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), "subfic $rD, $rA, $imm", IntGeneral, [(set GPRC:$rD, (sub immSExt16:$imm, GPRC:$rA))]>; -def LI : DForm_2_r0<14, (ops GPRC:$rD, s16imm:$imm), +def LI : DForm_2_r0<14, (ops GPRC:$rD, symbolLo:$imm), "li $rD, $imm", IntGeneral, [(set GPRC:$rD, immSExt16:$imm)]>; def LIS : DForm_2_r0<15, (ops GPRC:$rD, symbolHi:$imm), From lattner at cs.uiuc.edu Thu Nov 17 01:20:26 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 17 Nov 2005 01:20:26 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetSelectionDAG.td Message-ID: <200511170720.BAA25533@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetSelectionDAG.td updated: 1.9 -> 1.10 --- Log message: Add globaladdress and targetglobaladdress nodes for dag patterns --- Diffs of the changes: (+4 -0) TargetSelectionDAG.td | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Target/TargetSelectionDAG.td diff -u llvm/lib/Target/TargetSelectionDAG.td:1.9 llvm/lib/Target/TargetSelectionDAG.td:1.10 --- llvm/lib/Target/TargetSelectionDAG.td:1.9 Tue Nov 1 20:37:18 2005 +++ llvm/lib/Target/TargetSelectionDAG.td Thu Nov 17 01:20:15 2005 @@ -140,6 +140,10 @@ def vt : SDNode<"ISD::VALUETYPE" , SDTVT , [], "VTSDNode">; def cond : SDNode<"ISD::CONDCODE" , SDTVT , [], "CondCodeSDNode">; def undef : SDNode<"ISD::UNDEF" , SDTUNDEF , []>; +def globaladdr : SDNode<"ISD::GlobalAddress", SDTImm, [], + "GlobalAddressSDNode">; +def tglobaladdr : SDNode<"ISD::TargetGlobalAddress", SDTImm, [], + "GlobalAddressSDNode">; def add : SDNode<"ISD::ADD" , SDTIntBinOp , [SDNPCommutative, SDNPAssociative]>; def sub : SDNode<"ISD::SUB" , SDTIntBinOp>; From lattner at cs.uiuc.edu Thu Nov 17 01:30:53 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 17 Nov 2005 01:30:53 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp PPCISelLowering.cpp PPCISelLowering.h PPCInstrInfo.td Message-ID: <200511170730.BAA25698@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.127 -> 1.128 PPCISelLowering.cpp updated: 1.40 -> 1.41 PPCISelLowering.h updated: 1.9 -> 1.10 PPCInstrInfo.td updated: 1.140 -> 1.141 --- Log message: Add an initial hack at legalizing GlobalAddress into the appropriate nodes on Darwin to remove smarts from the isel. This is currently disabled by default (uncomment setOperationAction(ISD::GlobalAddress to enable it). tblgen needs to become smarter about tglobaladdr nodes and bigger patterns needed to be added to the .td file. However, we can currently emit stuff like this: :) li r2, lo16(L_x$non_lazy_ptr) lis r3, ha16(L_x$non_lazy_ptr) lwzx r2, r3, r2 The obvious improvements will follow. --- Diffs of the changes: (+52 -2) PPCISelDAGToDAG.cpp | 5 ++++- PPCISelLowering.cpp | 30 +++++++++++++++++++++++++++++- PPCISelLowering.h | 11 +++++++++++ PPCInstrInfo.td | 8 ++++++++ 4 files changed, 52 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.127 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.128 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.127 Wed Nov 16 23:56:14 2005 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Thu Nov 17 01:30:41 2005 @@ -872,7 +872,8 @@ case ISD::SETCC: return SelectSETCC(Op); case ISD::CALL: return SelectCALL(Op); case ISD::TAILCALL: return SelectCALL(Op); - + case PPCISD::GlobalBaseReg: return getGlobalBaseReg(); + case ISD::FrameIndex: { int FI = cast(N)->getIndex(); if (N->hasOneUse()) { @@ -898,6 +899,7 @@ } return CurDAG->getTargetNode(PPC::LA, MVT::i32, Tmp, CPI); } +#if 1 case ISD::GlobalAddress: { GlobalValue *GV = cast(N)->getGlobal(); SDOperand Tmp; @@ -912,6 +914,7 @@ else return CurDAG->getTargetNode(PPC::LA, MVT::i32, Tmp, GA); } +#endif case ISD::FADD: { MVT::ValueType Ty = N->getValueType(0); if (!NoExcessFPPrecision) { // Match FMA ops Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.40 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.41 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.40 Wed Nov 16 23:56:14 2005 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Thu Nov 17 01:30:41 2005 @@ -91,6 +91,10 @@ // PowerPC does not have truncstore for i1. setOperationAction(ISD::TRUNCSTORE, MVT::i1, Promote); + // We want to legalize GlobalAddress into the appropriate instructions to + // materialize the address. + //setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); + if (TM.getSubtarget().is64Bit()) { // They also have instructions for converting between i64 and fp. setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); @@ -98,7 +102,7 @@ // To take advantage of the above i64 FP_TO_SINT, promote i32 FP_TO_UINT setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote); } else { - // PowerPC does not have FP_TO_UINT on 32 bit implementations. + // PowerPC does not have FP_TO_UINT on 32-bit implementations. setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); } @@ -328,6 +332,30 @@ Tmp4, Tmp6, ISD::SETLE); return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); } + case ISD::GlobalAddress: { + // Only lower GlobalAddress on Darwin. + if (!getTargetMachine().getSubtarget().isDarwin()) break; + GlobalValue *GV = cast(Op)->getGlobal(); + SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32); + SDOperand Zero = DAG.getConstant(0, MVT::i32); + + SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, GA, Zero); + if (PICEnabled) { + // With PIC, the first instruction is actually "GR+hi(&G)". + Hi = DAG.getNode(ISD::ADD, MVT::i32, + DAG.getTargetNode(PPCISD::GlobalBaseReg, MVT::i32), Hi); + } + + SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, GA, Zero); + Lo = DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); + + if (!GV->hasWeakLinkage() && !GV->isExternal()) + return Lo; + + // If the global is weak or external, we have to go through the lazy + // resolution stub. + return DAG.getLoad(MVT::i32, DAG.getEntryNode(), Lo, DAG.getSrcValue(0)); + } } return SDOperand(); } Index: llvm/lib/Target/PowerPC/PPCISelLowering.h diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.9 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.10 --- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.9 Tue Oct 18 18:23:37 2005 +++ llvm/lib/Target/PowerPC/PPCISelLowering.h Thu Nov 17 01:30:41 2005 @@ -38,6 +38,17 @@ /// operand, producing an f64 value containing the integer representation /// of that FP value. FCTIDZ, FCTIWZ, + + /// Hi/Lo - These represent the high and low 16-bit parts of a global + /// address respectively. These nodes have two operands, the first of + /// which must be a TargetGlobalAddress, and the second of which must be a + /// Constant. Selected naively, these turn into 'lis G+C' and 'li G+C', + /// though these are usually folded into other nodes. + Hi, Lo, + + /// GlobalBaseReg - On Darwin, this node represents the result of the mflr + /// at function entry, used for PIC code. + GlobalBaseReg, }; } Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.140 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.141 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.140 Thu Nov 17 01:04:43 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Thu Nov 17 01:30:41 2005 @@ -27,6 +27,9 @@ SDTypeProfile<1, 3, [SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisFP<0>, SDTCisVT<1, f64>]>, []>; +def PPChi : SDNode<"PPCISD::Hi", SDTIntBinOp, []>; +def PPClo : SDNode<"PPCISD::Lo", SDTIntBinOp, []>; + //===----------------------------------------------------------------------===// // PowerPC specific transformation functions and pattern fragments. // @@ -782,6 +785,11 @@ def : Pat<(srl G8RC:$in, imm:$imm), (RLDICL G8RC:$in, (SRL64 imm:$imm), imm:$imm)>; +// Hi and Lo for Darwin Global Addresses. +def : Pat<(PPChi tglobaladdr:$in, (i32 0)), (LIS node:$in)>; +def : Pat<(PPClo tglobaladdr:$in, (i32 0)), (LI node:$in)>; + + // Same as above, but using a temporary. FIXME: implement temporaries :) /* def : Pattern<(xor GPRC:$in, imm:$imm), From lattner at cs.uiuc.edu Thu Nov 17 01:39:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 17 Nov 2005 01:39:56 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200511170739.BAA25802@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.74 -> 1.75 --- Log message: teach tblgen to be smart enough to handle tglobaladdr nodes --- Diffs of the changes: (+2 -0) DAGISelEmitter.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.74 llvm/utils/TableGen/DAGISelEmitter.cpp:1.75 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.74 Wed Nov 16 17:14:54 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Nov 17 01:39:45 2005 @@ -1668,6 +1668,8 @@ OS << ResNo << "C = cast(" << Val << ")->getValue();\n"; OS << " SDOperand Tmp" << ResNo << " = CurDAG->getTargetConstant(Tmp" << ResNo << "C, MVT::" << getEnumName(N->getType()) << ");\n"; + } else if (!N->isLeaf() && N->getOperator()->getName() == "tglobaladdr") { + OS << " SDOperand Tmp" << ResNo << " = " << Val << ";\n"; } else { OS << " SDOperand Tmp" << ResNo << " = Select(" << Val << ");\n"; } From lattner at cs.uiuc.edu Thu Nov 17 10:08:23 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 17 Nov 2005 10:08:23 -0600 Subject: [llvm-commits] CVS: llvm/tools/gccld/gccld.cpp Message-ID: <200511171608.KAA26925@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: gccld.cpp updated: 1.103 -> 1.104 --- Log message: Allow users to specify -Wl,-native* multiple times if they please --- Diffs of the changes: (+2 -2) gccld.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/tools/gccld/gccld.cpp diff -u llvm/tools/gccld/gccld.cpp:1.103 llvm/tools/gccld/gccld.cpp:1.104 --- llvm/tools/gccld/gccld.cpp:1.103 Tue Aug 2 17:07:38 2005 +++ llvm/tools/gccld/gccld.cpp Thu Nov 17 10:08:04 2005 @@ -78,10 +78,10 @@ cl::aliasopt(LinkAsLibrary)); cl::opt - Native("native", + Native("native", cl::ZeroOrMore, cl::desc("Generate a native binary instead of a shell script")); cl::opt - NativeCBE("native-cbe", + NativeCBE("native-cbe", cl::ZeroOrMore, cl::desc("Generate a native binary with the C backend and GCC")); cl::opt From lattner at cs.uiuc.edu Thu Nov 17 11:44:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 17 Nov 2005 11:44:05 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200511171744.LAA29372@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.75 -> 1.76 --- Log message: Validate that the input to 'Pat' patterns is sane. --- Diffs of the changes: (+8 -0) DAGISelEmitter.cpp | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.75 llvm/utils/TableGen/DAGISelEmitter.cpp:1.76 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.75 Thu Nov 17 01:39:45 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Thu Nov 17 11:43:52 2005 @@ -1212,6 +1212,14 @@ // never do anything with this pattern: report it to the user. if (!Pattern->InferAllTypes()) Pattern->error("Could not infer all types in pattern!"); + + // Validate that the input pattern is correct. + { + std::map InstInputs; + std::map InstResults; + FindPatternInputsAndOutputs(Pattern, Pattern->getOnlyTree(), + InstInputs, InstResults); + } ListInit *LI = Patterns[i]->getValueAsListInit("ResultInstrs"); if (LI->getSize() == 0) continue; // no pattern. From lattner at cs.uiuc.edu Thu Nov 17 11:51:50 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 17 Nov 2005 11:51:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp Message-ID: <200511171751.LAA02092@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.41 -> 1.42 --- Log message: Use the right accessor to create this node --- Diffs of the changes: (+1 -1) PPCISelLowering.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.41 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.42 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.41 Thu Nov 17 01:30:41 2005 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Thu Nov 17 11:51:38 2005 @@ -343,7 +343,7 @@ if (PICEnabled) { // With PIC, the first instruction is actually "GR+hi(&G)". Hi = DAG.getNode(ISD::ADD, MVT::i32, - DAG.getTargetNode(PPCISD::GlobalBaseReg, MVT::i32), Hi); + DAG.getNode(PPCISD::GlobalBaseReg, MVT::i32), Hi); } SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, GA, Zero); From lattner at cs.uiuc.edu Thu Nov 17 11:52:12 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 17 Nov 2005 11:52:12 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCInstrInfo.td Message-ID: <200511171752.LAA02128@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCInstrInfo.td updated: 1.141 -> 1.142 --- Log message: Generate LA and ADDIS when possible. --- Diffs of the changes: (+6 -4) PPCInstrInfo.td | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.141 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.142 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.141 Thu Nov 17 01:30:41 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Thu Nov 17 11:52:01 2005 @@ -256,7 +256,8 @@ [(set GPRC:$rD, (add GPRC:$rA, imm16Shifted:$imm))]>; def LA : DForm_2<14, (ops GPRC:$rD, GPRC:$rA, symbolLo:$sym), "la $rD, $sym($rA)", IntGeneral, - []>; + [(set GPRC:$rD, (add GPRC:$rA, + (PPClo tglobaladdr:$sym, 0)))]>; def MULLI : DForm_2< 7, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), "mulli $rD, $rA, $imm", IntMulLI, [(set GPRC:$rD, (mul GPRC:$rA, immSExt16:$imm))]>; @@ -786,9 +787,10 @@ (RLDICL G8RC:$in, (SRL64 imm:$imm), imm:$imm)>; // Hi and Lo for Darwin Global Addresses. -def : Pat<(PPChi tglobaladdr:$in, (i32 0)), (LIS node:$in)>; -def : Pat<(PPClo tglobaladdr:$in, (i32 0)), (LI node:$in)>; - +def : Pat<(PPChi tglobaladdr:$in, (i32 0)), (LIS tglobaladdr:$in)>; +def : Pat<(PPClo tglobaladdr:$in, (i32 0)), (LI tglobaladdr:$in)>; +def : Pat<(add GPRC:$in, (PPChi tglobaladdr:$g, 0)), + (ADDIS GPRC:$in, tglobaladdr:$g)>; // Same as above, but using a temporary. FIXME: implement temporaries :) /* From lattner at cs.uiuc.edu Thu Nov 17 12:02:28 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 17 Nov 2005 12:02:28 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Message-ID: <200511171802.MAA02249@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.128 -> 1.129 --- Log message: Teach the selector to fold lo(g) into load instruction immediate fields --- Diffs of the changes: (+8 -0) PPCISelDAGToDAG.cpp | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.128 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.129 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.128 Thu Nov 17 01:30:41 2005 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Thu Nov 17 12:02:16 2005 @@ -413,6 +413,14 @@ Op2 = Select(Addr.getOperand(0)); } return false; + } else if (Addr.getOperand(1).getOpcode() == PPCISD::Lo) { + // Match LOAD (ADD (X, Lo(G))). + assert(!cast(Addr.getOperand(1).getOperand(1))->getValue() + && "Cannot handle constant offsets yet!"); + Op1 = Addr.getOperand(1).getOperand(0); // The global address. + assert(Op1.getOpcode() == ISD::TargetGlobalAddress); + Op2 = Select(Addr.getOperand(0)); + return false; // [&g+r] } else { Op1 = Select(Addr.getOperand(0)); Op2 = Select(Addr.getOperand(1)); From lattner at cs.uiuc.edu Thu Nov 17 12:27:07 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 17 Nov 2005 12:27:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp PPCISelLowering.cpp README.txt Message-ID: <200511171827.MAA02660@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.129 -> 1.130 PPCISelLowering.cpp updated: 1.42 -> 1.43 README.txt updated: 1.38 -> 1.39 --- Log message: Enable global address legalization, fixing a todo and allowing the removal of some code. This exposes the implicit load from the stubs to the DAG, allowing them to be optimized by the dag combiner. It also moves darwin specific stuff out of the isel into the legalizer, and allows more to be moved to the .td file. --- Diffs of the changes: (+2 -49) PPCISelDAGToDAG.cpp | 31 +------------------------------ PPCISelLowering.cpp | 2 +- README.txt | 18 ------------------ 3 files changed, 2 insertions(+), 49 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.129 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.130 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.129 Thu Nov 17 12:02:16 2005 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Thu Nov 17 12:26:56 2005 @@ -428,20 +428,7 @@ } } - // Now check if we're dealing with a global, and whether or not we should emit - // an optimized load or store for statics. - if (GlobalAddressSDNode *GN = dyn_cast(Addr)) { - GlobalValue *GV = GN->getGlobal(); - if (!GV->hasWeakLinkage() && !GV->isExternal()) { - Op1 = CurDAG->getTargetGlobalAddress(GV, MVT::i32); - if (PICEnabled) - Op2 = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(), - Op1); - else - Op2 = CurDAG->getTargetNode(PPC::LIS, MVT::i32, Op1); - return false; - } - } else if (FrameIndexSDNode *FI = dyn_cast(Addr)) { + if (FrameIndexSDNode *FI = dyn_cast(Addr)) { Op1 = getI32Imm(0); Op2 = CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32); return false; @@ -907,22 +894,6 @@ } return CurDAG->getTargetNode(PPC::LA, MVT::i32, Tmp, CPI); } -#if 1 - case ISD::GlobalAddress: { - GlobalValue *GV = cast(N)->getGlobal(); - SDOperand Tmp; - SDOperand GA = CurDAG->getTargetGlobalAddress(GV, MVT::i32); - if (PICEnabled) - Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(), GA); - else - Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, GA); - - if (GV->hasWeakLinkage() || GV->isExternal()) - return CurDAG->getTargetNode(PPC::LWZ, MVT::i32, GA, Tmp); - else - return CurDAG->getTargetNode(PPC::LA, MVT::i32, Tmp, GA); - } -#endif case ISD::FADD: { MVT::ValueType Ty = N->getValueType(0); if (!NoExcessFPPrecision) { // Match FMA ops Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.42 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.43 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.42 Thu Nov 17 11:51:38 2005 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Thu Nov 17 12:26:56 2005 @@ -93,7 +93,7 @@ // We want to legalize GlobalAddress into the appropriate instructions to // materialize the address. - //setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); + setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); if (TM.getSubtarget().is64Bit()) { // They also have instructions for converting between i64 and fp. Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.38 llvm/lib/Target/PowerPC/README.txt:1.39 --- llvm/lib/Target/PowerPC/README.txt:1.38 Sat Nov 5 02:57:56 2005 +++ llvm/lib/Target/PowerPC/README.txt Thu Nov 17 12:26:56 2005 @@ -31,24 +31,6 @@ * Support 'update' load/store instructions. These are cracked on the G5, but are still a codesize win. -* Add a custom legalizer for the GlobalAddress node, to move the funky darwin - stub stuff from the instruction selector to the legalizer (exposing low-level - operations to the dag for optzn. For example, we want to codegen this: - - int A = 0; - void B() { A++; } - as: - lis r9,ha16(_A) - lwz r2,lo16(_A)(r9) - addi r2,r2,1 - stw r2,lo16(_A)(r9) - not: - lis r2, ha16(_A) - lwz r2, lo16(_A)(r2) - addi r2, r2, 1 - lis r3, ha16(_A) - stw r2, lo16(_A)(r3) - * should hint to the branch select pass that it doesn't need to print the second unconditional branch, so we don't end up with things like: b .LBBl42__2E_expand_function_8_674 ; loopentry.24 From lattner at cs.uiuc.edu Thu Nov 17 12:30:29 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 17 Nov 2005 12:30:29 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp Message-ID: <200511171830.MAA02735@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.43 -> 1.44 --- Log message: Fix a bug that resistor on IRC hit where we tried to create token factor nodes of load results, not of their chain results. --- Diffs of the changes: (+2 -2) PPCISelLowering.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.43 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.44 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.43 Thu Nov 17 12:26:56 2005 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Thu Nov 17 12:30:17 2005 @@ -670,7 +670,7 @@ if (GPR_remaining > 0) { SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff, DAG.getSrcValue(NULL)); - MemOps.push_back(Load); + MemOps.push_back(Load.getValue(1)); args_to_use.push_back(Load); --GPR_remaining; } @@ -679,7 +679,7 @@ PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff, DAG.getSrcValue(NULL)); - MemOps.push_back(Load); + MemOps.push_back(Load.getValue(1)); args_to_use.push_back(Load); --GPR_remaining; } From lattner at cs.uiuc.edu Thu Nov 17 12:55:59 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 17 Nov 2005 12:55:59 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC.h PPCISelLowering.cpp PPCSubtarget.cpp Message-ID: <200511171855.MAA02828@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPC.h updated: 1.23 -> 1.24 PPCISelLowering.cpp updated: 1.44 -> 1.45 PPCSubtarget.cpp updated: 1.15 -> 1.16 --- Log message: add an option to generate completely non-pic code, corresponding to what gcc -static produces on PPC. This is used for building kexts and other things. With this, materializing the address of a global looks like: lis r2, ha16(L_H$non_lazy_ptr) la r3, lo16(L_H$non_lazy_ptr)(r2) we're still emitting stubs for functions, which is wrong. That is next. --- Diffs of the changes: (+17 -2) PPC.h | 1 + PPCISelLowering.cpp | 12 ++++++++++-- PPCSubtarget.cpp | 6 ++++++ 3 files changed, 17 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPC.h diff -u llvm/lib/Target/PowerPC/PPC.h:1.23 llvm/lib/Target/PowerPC/PPC.h:1.24 --- llvm/lib/Target/PowerPC/PPC.h:1.23 Mon Oct 17 19:28:58 2005 +++ llvm/lib/Target/PowerPC/PPC.h Thu Nov 17 12:55:48 2005 @@ -33,6 +33,7 @@ FunctionPass *createAIXAsmPrinter(std::ostream &OS, TargetMachine &TM); extern bool PICEnabled; +extern bool PPCGenerateStaticCode; extern PPCTargetEnum PPCTarget; } // end namespace llvm; Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.44 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.45 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.44 Thu Nov 17 12:30:17 2005 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Thu Nov 17 12:55:48 2005 @@ -333,12 +333,20 @@ return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); } case ISD::GlobalAddress: { - // Only lower GlobalAddress on Darwin. - if (!getTargetMachine().getSubtarget().isDarwin()) break; GlobalValue *GV = cast(Op)->getGlobal(); SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32); SDOperand Zero = DAG.getConstant(0, MVT::i32); + + if (PPCGenerateStaticCode) { + // Generate non-pic code that has direct accesses to globals. To do this + // the address of the global is just (hi(&g)+lo(&g)). + SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, GA, Zero); + SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, GA, Zero); + return DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); + } + // Only lower GlobalAddress on Darwin. + if (!getTargetMachine().getSubtarget().isDarwin()) break; SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, GA, Zero); if (PICEnabled) { // With PIC, the first instruction is actually "GR+hi(&G)". Index: llvm/lib/Target/PowerPC/PPCSubtarget.cpp diff -u llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.15 llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.16 --- llvm/lib/Target/PowerPC/PPCSubtarget.cpp:1.15 Tue Nov 1 14:07:00 2005 +++ llvm/lib/Target/PowerPC/PPCSubtarget.cpp Thu Nov 17 12:55:48 2005 @@ -19,6 +19,7 @@ using namespace llvm; PPCTargetEnum llvm::PPCTarget = TargetDefault; +bool llvm::PPCGenerateStaticCode = false; namespace llvm { cl::opt @@ -29,6 +30,11 @@ " Enable Darwin codegen"), clEnumValEnd), cl::location(PPCTarget), cl::init(TargetDefault)); + + cl::opt + PPCStaticCode("ppc-static", + cl::desc("PowerPC: generate completely non-pic code"), + cl::location(PPCGenerateStaticCode)); } #if defined(__APPLE__) From lattner at cs.uiuc.edu Thu Nov 17 13:16:19 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 17 Nov 2005 13:16:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp PPCInstrInfo.td Message-ID: <200511171916.NAA02962@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.110 -> 1.111 PPCInstrInfo.td updated: 1.142 -> 1.143 --- Log message: disentangle call operands from branch operands a bit --- Diffs of the changes: (+9 -3) PPCAsmPrinter.cpp | 7 +++++-- PPCInstrInfo.td | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.110 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.111 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.110 Tue Nov 15 18:48:01 2005 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Thu Nov 17 13:16:08 2005 @@ -148,10 +148,13 @@ if (MI->getOperand(OpNo).isImmediate()) { O << "$+" << MI->getOperand(OpNo).getImmedValue(); } else { - printOp(MI->getOperand(OpNo), - TM.getInstrInfo()->isCall(MI->getOpcode())); + printOp(MI->getOperand(OpNo)); } } + void printCallOperand(const MachineInstr *MI, unsigned OpNo, + MVT::ValueType VT) { + printOp(MI->getOperand(OpNo), true); + } void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT) { O << (int)MI->getOperand(OpNo).getImmedValue()*4; Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.142 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.143 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.142 Thu Nov 17 11:52:01 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Thu Nov 17 13:16:08 2005 @@ -131,6 +131,9 @@ def target : Operand { let PrintMethod = "printBranchOperand"; } +def calltarget : Operand { + let PrintMethod = "printCallOperand"; +} def aaddr : Operand { let PrintMethod = "printAbsAddrOperand"; } @@ -220,7 +223,7 @@ LR,CTR, CR0,CR1,CR5,CR6,CR7] in { // Convenient aliases for call instructions - def BL : IForm<18, 0, 1, (ops target:$func, variable_ops), "bl $func", BrB>; + def BL : IForm<18, 0, 1, (ops calltarget:$func, variable_ops), "bl $func", BrB>; def BLA : IForm<18, 1, 1, (ops aaddr:$func, variable_ops), "bla $func", BrB>; def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (ops variable_ops), "bctrl", BrB>; } From lattner at cs.uiuc.edu Thu Nov 17 13:26:11 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 17 Nov 2005 13:26:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Message-ID: <200511171926.NAA03055@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.111 -> 1.112 --- Log message: refactor call operand handling to eliminate special cases from printOp. --- Diffs of the changes: (+17 -19) PPCAsmPrinter.cpp | 36 +++++++++++++++++------------------- 1 files changed, 17 insertions(+), 19 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.111 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.112 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.111 Thu Nov 17 13:16:08 2005 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Thu Nov 17 13:25:59 2005 @@ -103,7 +103,7 @@ bool printInstruction(const MachineInstr *MI); void printMachineInstruction(const MachineInstr *MI); - void printOp(const MachineOperand &MO, bool IsCallOp = false); + void printOp(const MachineOperand &MO); void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){ const MachineOperand &MO = MI->getOperand(OpNo); @@ -153,7 +153,21 @@ } void printCallOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT) { - printOp(MI->getOperand(OpNo), true); + const MachineOperand &MO = MI->getOperand(OpNo); + if (MO.getType() == MachineOperand::MO_ExternalSymbol) { + std::string Name(GlobalPrefix); Name += MO.getSymbolName(); + FnStubs.insert(Name); + O << "L" << Name << "$stub"; + } else if (MO.getType() == MachineOperand::MO_GlobalAddress && + isa(MO.getGlobal()) && + cast(MO.getGlobal())->isExternal()) { + // Dynamically-resolved functions need a stub for the function. + std::string Name = Mang->getValueName(MO.getGlobal()); + FnStubs.insert(Name); + O << "L" << Name << "$stub"; + } else { + printOp(MI->getOperand(OpNo)); + } } void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT) { @@ -273,7 +287,7 @@ // Include the auto-generated portion of the assembly writer #include "PPCGenAsmWriter.inc" -void PPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) { +void PPCAsmPrinter::printOp(const MachineOperand &MO) { const MRegisterInfo &RI = *TM.getRegisterInfo(); int new_symbol; @@ -312,12 +326,6 @@ return; case MachineOperand::MO_ExternalSymbol: - if (IsCallOp) { - std::string Name(GlobalPrefix); Name += MO.getSymbolName(); - FnStubs.insert(Name); - O << "L" << Name << "$stub"; - return; - } O << GlobalPrefix << MO.getSymbolName(); return; @@ -325,16 +333,6 @@ GlobalValue *GV = MO.getGlobal(); std::string Name = Mang->getValueName(GV); - // Dynamically-resolved functions need a stub for the function. Be - // wary however not to output $stub for external functions whose addresses - // are taken. Those should be emitted as $non_lazy_ptr below. - Function *F = dyn_cast(GV); - if (F && IsCallOp && F->isExternal()) { - FnStubs.insert(Name); - O << "L" << Name << "$stub"; - return; - } - // External or weakly linked global variables need non-lazily-resolved stubs if ((GV->isExternal() || GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())){ if (GV->hasLinkOnceLinkage()) From lattner at cs.uiuc.edu Thu Nov 17 13:35:53 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 17 Nov 2005 13:35:53 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <200511171935.NAA03132@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: IndVarSimplify.cpp updated: 1.80 -> 1.81 --- Log message: This was checking the wrong GEP expression. Fixing this fixes a gccas crash compiling mysql reported by Ted Kremenek. --- Diffs of the changes: (+1 -1) IndVarSimplify.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp diff -u llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.80 llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.81 --- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.80 Tue Aug 9 20:12:06 2005 +++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Thu Nov 17 13:35:42 2005 @@ -162,7 +162,7 @@ if (CE->getOperand(NumOps-1)->isNullValue()) { // Check to make sure the last index really is an array index. gep_type_iterator GTI = gep_type_begin(GEPI); - for (unsigned i = 1, e = GEPI->getNumOperands()-1; + for (unsigned i = 1, e = CE->getNumOperands()-1; i != e; ++i, ++GTI) /*empty*/; if (isa(*GTI)) { From lattner at cs.uiuc.edu Thu Nov 17 13:40:41 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 17 Nov 2005 13:40:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Message-ID: <200511171940.NAA03197@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.112 -> 1.113 --- Log message: only use dyld stubs if not in ppc-static mode. This completes support for non-static codegen. --- Diffs of the changes: (+21 -15) PPCAsmPrinter.cpp | 36 +++++++++++++++++++++--------------- 1 files changed, 21 insertions(+), 15 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.112 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.113 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.112 Thu Nov 17 13:25:59 2005 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Thu Nov 17 13:40:30 2005 @@ -154,20 +154,24 @@ void printCallOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT) { const MachineOperand &MO = MI->getOperand(OpNo); - if (MO.getType() == MachineOperand::MO_ExternalSymbol) { - std::string Name(GlobalPrefix); Name += MO.getSymbolName(); - FnStubs.insert(Name); - O << "L" << Name << "$stub"; - } else if (MO.getType() == MachineOperand::MO_GlobalAddress && - isa(MO.getGlobal()) && - cast(MO.getGlobal())->isExternal()) { - // Dynamically-resolved functions need a stub for the function. - std::string Name = Mang->getValueName(MO.getGlobal()); - FnStubs.insert(Name); - O << "L" << Name << "$stub"; - } else { - printOp(MI->getOperand(OpNo)); + if (!PPCGenerateStaticCode) { + if (MO.getType() == MachineOperand::MO_ExternalSymbol) { + std::string Name(GlobalPrefix); Name += MO.getSymbolName(); + FnStubs.insert(Name); + O << "L" << Name << "$stub"; + return; + } else if (MO.getType() == MachineOperand::MO_GlobalAddress && + isa(MO.getGlobal()) && + cast(MO.getGlobal())->isExternal()) { + // Dynamically-resolved functions need a stub for the function. + std::string Name = Mang->getValueName(MO.getGlobal()); + FnStubs.insert(Name); + O << "L" << Name << "$stub"; + return; + } } + + printOp(MI->getOperand(OpNo)); } void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT) { @@ -334,7 +338,9 @@ std::string Name = Mang->getValueName(GV); // External or weakly linked global variables need non-lazily-resolved stubs - if ((GV->isExternal() || GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())){ + if (!PPCGenerateStaticCode && + ((GV->isExternal() || GV->hasWeakLinkage() || + GV->hasLinkOnceLinkage()))) { if (GV->hasLinkOnceLinkage()) LinkOnceStubs.insert(Name); else @@ -343,7 +349,7 @@ return; } - O << Mang->getValueName(GV); + O << Name; return; } From natebegeman at mac.com Thu Nov 17 15:44:54 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 17 Nov 2005 15:44:54 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h Message-ID: <200511172144.PAA04224@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.27 -> 1.28 --- Log message: Teach the type lowering code about turning packed types into vector types. Next step: generating vector dag nodes, and legalizing them into scalar code. --- Diffs of the changes: (+1 -0) TargetLowering.h | 1 + 1 files changed, 1 insertion(+) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.27 llvm/include/llvm/Target/TargetLowering.h:1.28 --- llvm/include/llvm/Target/TargetLowering.h:1.27 Thu Oct 20 19:02:42 2005 +++ llvm/include/llvm/Target/TargetLowering.h Thu Nov 17 15:44:42 2005 @@ -189,6 +189,7 @@ case Type::FloatTyID: return MVT::f32; case Type::DoubleTyID: return MVT::f64; case Type::PointerTyID: return PointerTy; + case Type::PackedTyID: return MVT::Vector; } } From natebegeman at mac.com Thu Nov 17 15:44:54 2005 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 17 Nov 2005 15:44:54 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ValueTypes.h Message-ID: <200511172144.PAA04228@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ValueTypes.h updated: 1.12 -> 1.13 --- Log message: Teach the type lowering code about turning packed types into vector types. Next step: generating vector dag nodes, and legalizing them into scalar code. --- Diffs of the changes: (+9 -5) ValueTypes.h | 14 +++++++++----- 1 files changed, 9 insertions(+), 5 deletions(-) Index: llvm/include/llvm/CodeGen/ValueTypes.h diff -u llvm/include/llvm/CodeGen/ValueTypes.h:1.12 llvm/include/llvm/CodeGen/ValueTypes.h:1.13 --- llvm/include/llvm/CodeGen/ValueTypes.h:1.12 Thu Aug 25 12:06:34 2005 +++ llvm/include/llvm/CodeGen/ValueTypes.h Thu Nov 17 15:44:42 2005 @@ -36,13 +36,17 @@ i64 = 5, // This is a 64 bit integer value i128 = 6, // This is a 128 bit integer value - f32 = 7, // This is a 32 bit floating point value - f64 = 8, // This is a 64 bit floating point value - f80 = 9, // This is a 80 bit floating point value - f128 = 10, // This is a 128 bit floating point value + f32 = 7, // This is a 32 bit floating point value + f64 = 8, // This is a 64 bit floating point value + f80 = 9, // This is a 80 bit floating point value + f128 = 10, // This is a 128 bit floating point value Flag = 11, // This is a condition code or machine flag. - isVoid = 12, // This has no value + isVoid = 12, // This has no value + + Vector = 13, // This is an abstract vector type, which will + // be refined into a target vector type, or + // scalarized. LAST_VALUETYPE, // This always remains at the end of the list. }; From dhurjati at cs.uiuc.edu Thu Nov 17 15:46:42 2005 From: dhurjati at cs.uiuc.edu (Dinakar Dhurjati) Date: Thu, 17 Nov 2005 15:46:42 -0600 Subject: [llvm-commits] CVS: llvm-www/pubs/2005-11-SAFECodeTR.html 2005-11-SAFECodeTR.pdf 2003-04-29-DataStructureAnalysisTR.html Message-ID: <200511172146.PAA04267@zion.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2005-11-SAFECodeTR.html added (r1.1) 2005-11-SAFECodeTR.pdf added (r1.1) 2003-04-29-DataStructureAnalysisTR.html updated: 1.7 -> 1.8 --- Log message: Added safecode tech report --- Diffs of the changes: (+73 -9) 2003-04-29-DataStructureAnalysisTR.html | 12 +---- 2005-11-SAFECodeTR.html | 70 ++++++++++++++++++++++++++++++++ 2005-11-SAFECodeTR.pdf | 0 3 files changed, 73 insertions(+), 9 deletions(-) Index: llvm-www/pubs/2005-11-SAFECodeTR.html diff -c /dev/null llvm-www/pubs/2005-11-SAFECodeTR.html:1.1 *** /dev/null Thu Nov 17 15:46:40 2005 --- llvm-www/pubs/2005-11-SAFECodeTR.html Thu Nov 17 15:46:30 2005 *************** *** 0 **** --- 1,70 ---- + + + + + + Enforcing Alias Analysis for Weakly Typed Languages + + + +
    + Enforcing Alias Analysis for Weakly Typed Languages +
    +
    + Dinakar Dhurjati, Sumant Kowshik, and Vikram Adve +
    + + +

    Abstract:

    +
    + +

    + Static analysis of programs in weakly typed languages such as C and C++ is + generally not sound because of possible memory errors due to dangling + pointer references, uninitialized pointers, and array bounds overflow. + Optimizing compilers can produce unpredictable results when such errors + occur, but this is quite undesirable for many tools that aim to analyze + security and reliability properties with guarantees of soundness. We + describe a relatively simple compilation strategy for standard C programs + that guarantees sound semantics for an aggressive interprocedural pointer + analysis (or simpler ones), a call graph, and type information for a + subset of memory. These provide the foundation for sophisticated static + analyses to be applied to such programs with a guarantee of soundness. Our + work builds on a previously published transformation called Automatic Pool + Allocation to ensure that hard-to-detect memory errors (dangling pointer + references and certain array bounds errors) cannot invalidate the call + graph, points-to information or type information. The key insights behind + our approach is that pool allocation can be used to create a run-time + partitioning of memory that matches the compile-time memory partitioning + in a points-to graph, and efficient checks can be used to isolate the + run-time partitions. Furthermore, we show that the sound analysis + information enables static checking techniques that reliably eliminate + many run-time checks. We formalize our approach as a new type system with + the necessary run-time checks in operational semantics and prove the + correctness of our approach for a subset of C. Our approach requires no + source code changes, allows memory to be managed explicitly, and does not + use meta-data on pointers or individual tag bits for memory. Using several + benchmarks and system codes, we show experimentally that the run-time + overheads are low (less than 10% in nearly all cases and 30% in the worst + case we have seen). We also show the effectiveness of reliable static + analyses for eliminating run-time checks. + +

    +
    + +

    Published:

    +
    + "Enforcing Alias Analysis for Weakly Typed Languages"
    + By Dinakar Dhurjati, Sumant Kowshik, and Vikram Adve.
    + Technical Report #UIUCDCS-R-2005-2657, Computer Science Dept., Univ. of + Illinois, Nov. 2005 +
    + +

    Download:

    + + + + Index: llvm-www/pubs/2005-11-SAFECodeTR.pdf Index: llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html diff -u llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html:1.7 llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html:1.8 --- llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html:1.7 Sat Apr 17 15:13:02 2004 +++ llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html Thu Nov 17 15:46:30 2005 @@ -35,19 +35,13 @@
    "Data Structure Analysis: An Efficient Context-Sensitive Heap Analysis", Chris Lattner & Vikram Adve
    - Technical Report #UIUCDCS-R-2003-2340, Computer Science Dept., Univ. of - Illinois, Apr. 2003. -
    - -

    Update:

    -
    - This document was updated on 15 November 2003 to reflect improvements to the - algorithm, and to be more clear and precise. + Technical Report #UIUCDCS-R-2005-2657, Computer Science Dept., Univ. of + Illinois, Nov. 2005.

    Download:

      -
    • Data Structure Analysis: +
    • Data Structure Analysis: An Efficient Context-Sensitive Heap Analysis (PS)
    • Data Structure Analysis: An Efficient Context-Sensitive Heap Analysis (PDF)
    • From dhurjati at cs.uiuc.edu Thu Nov 17 15:51:10 2005 From: dhurjati at cs.uiuc.edu (Dinakar Dhurjati) Date: Thu, 17 Nov 2005 15:51:10 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/index.html Message-ID: <200511172151.PAA04313@zion.cs.uiuc.edu> Changes in directory llvm-www/safecode: index.html updated: 1.10 -> 1.11 --- Log message: Added safecode tech report --- Diffs of the changes: (+4 -1) index.html | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm-www/safecode/index.html diff -u llvm-www/safecode/index.html:1.10 llvm-www/safecode/index.html:1.11 --- llvm-www/safecode/index.html:1.10 Tue May 3 18:43:30 2005 +++ llvm-www/safecode/index.html Thu Nov 17 15:50:58 2005 @@ -39,7 +39,10 @@

      Publications

        -
      • "Memory Safety Without +
      • " Enforcing Alias Analysis for Weakly Typed Languages " +
        + Dinakar dhurjati, Sumant Kowshik, and Vikram Adve. UIUC TechReport
      • +
      • "Memory Safety Without Garbage Collection for Embedded Applications"
        Dinakar Dhurjati, Sumant Kowshik, Vikram Adve and Chris Lattner. ACM Transactions in From dhurjati at cs.uiuc.edu Thu Nov 17 15:53:43 2005 From: dhurjati at cs.uiuc.edu (Dinakar Dhurjati) Date: Thu, 17 Nov 2005 15:53:43 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/index.html Message-ID: <200511172153.PAA04385@zion.cs.uiuc.edu> Changes in directory llvm-www/safecode: index.html updated: 1.11 -> 1.12 --- Log message: *** empty log message *** --- Diffs of the changes: (+1 -0) index.html | 1 + 1 files changed, 1 insertion(+) Index: llvm-www/safecode/index.html diff -u llvm-www/safecode/index.html:1.11 llvm-www/safecode/index.html:1.12 --- llvm-www/safecode/index.html:1.11 Thu Nov 17 15:50:58 2005 +++ llvm-www/safecode/index.html Thu Nov 17 15:53:31 2005 @@ -39,6 +39,7 @@

        Publications

          +

          Tech Report of PLDI submission

        • " Enforcing Alias Analysis for Weakly Typed Languages "
          Dinakar dhurjati, Sumant Kowshik, and Vikram Adve. UIUC TechReport
        • From dhurjati at cs.uiuc.edu Thu Nov 17 15:56:00 2005 From: dhurjati at cs.uiuc.edu (Dinakar Dhurjati) Date: Thu, 17 Nov 2005 15:56:00 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/index.html Message-ID: <200511172156.PAA04440@zion.cs.uiuc.edu> Changes in directory llvm-www/safecode: index.html updated: 1.12 -> 1.13 --- Log message: *** empty log message *** --- Diffs of the changes: (+2 -2) index.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm-www/safecode/index.html diff -u llvm-www/safecode/index.html:1.12 llvm-www/safecode/index.html:1.13 --- llvm-www/safecode/index.html:1.12 Thu Nov 17 15:53:31 2005 +++ llvm-www/safecode/index.html Thu Nov 17 15:55:49 2005 @@ -39,8 +39,8 @@

          Publications

            -

            Tech Report of PLDI submission

            -
          • " Enforcing Alias Analysis for Weakly Typed Languages " +
          • Tech Report of PLDI submission


            +" Enforcing Alias Analysis for Weakly Typed Languages "
            Dinakar dhurjati, Sumant Kowshik, and Vikram Adve. UIUC TechReport
          • "Memory Safety Without From dhurjati at cs.uiuc.edu Thu Nov 17 15:56:18 2005 From: dhurjati at cs.uiuc.edu (Dinakar Dhurjati) Date: Thu, 17 Nov 2005 15:56:18 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/index.html Message-ID: <200511172156.PAA04467@zion.cs.uiuc.edu> Changes in directory llvm-www/safecode: index.html updated: 1.13 -> 1.14 --- Log message: *** empty log message *** --- Diffs of the changes: (+1 -1) index.html | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-www/safecode/index.html diff -u llvm-www/safecode/index.html:1.13 llvm-www/safecode/index.html:1.14 --- llvm-www/safecode/index.html:1.13 Thu Nov 17 15:55:49 2005 +++ llvm-www/safecode/index.html Thu Nov 17 15:56:06 2005 @@ -39,7 +39,7 @@

            Publications

              -
            • Tech Report of PLDI submission


              +
            • Tech Report of PLDI submission

              "
              Enforcing Alias Analysis for Weakly Typed Languages "
              Dinakar dhurjati, Sumant Kowshik, and Vikram Adve. UIUC TechReport
            • From dhurjati at cs.uiuc.edu Thu Nov 17 15:57:03 2005 From: dhurjati at cs.uiuc.edu (Dinakar Dhurjati) Date: Thu, 17 Nov 2005 15:57:03 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/index.html Message-ID: <200511172157.PAA04503@zion.cs.uiuc.edu> Changes in directory llvm-www/safecode: index.html updated: 1.14 -> 1.15 --- Log message: *** empty log message *** --- Diffs of the changes: (+1 -2) index.html | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm-www/safecode/index.html diff -u llvm-www/safecode/index.html:1.14 llvm-www/safecode/index.html:1.15 --- llvm-www/safecode/index.html:1.14 Thu Nov 17 15:56:06 2005 +++ llvm-www/safecode/index.html Thu Nov 17 15:56:52 2005 @@ -39,8 +39,7 @@

              Publications

                -
              • Tech Report of PLDI submission

                -" Enforcing Alias Analysis for Weakly Typed Languages " +
              • Tech Report of PLDI submission

                " Enforcing Alias Analysis for Weakly Typed Languages "
                Dinakar dhurjati, Sumant Kowshik, and Vikram Adve. UIUC TechReport
              • "Memory Safety Without From dhurjati at cs.uiuc.edu Thu Nov 17 15:58:46 2005 From: dhurjati at cs.uiuc.edu (Dinakar Dhurjati) Date: Thu, 17 Nov 2005 15:58:46 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/index.html Message-ID: <200511172158.PAA04531@zion.cs.uiuc.edu> Changes in directory llvm-www/safecode: index.html updated: 1.15 -> 1.16 --- Log message: *** empty log message *** --- Diffs of the changes: (+3 -1) index.html | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm-www/safecode/index.html diff -u llvm-www/safecode/index.html:1.15 llvm-www/safecode/index.html:1.16 --- llvm-www/safecode/index.html:1.15 Thu Nov 17 15:56:52 2005 +++ llvm-www/safecode/index.html Thu Nov 17 15:58:35 2005 @@ -41,7 +41,9 @@
                • Tech Report of PLDI submission

                  "
                  Enforcing Alias Analysis for Weakly Typed Languages "
                  - Dinakar dhurjati, Sumant Kowshik, and Vikram Adve. UIUC TechReport
                • + Dinakar dhurjati, Sumant Kowshik, and Vikram Adve. Technical Report + #UIUCDCS-R-2005-2657, Computer Science Dept., University of + Illinois, Nov 2005
                • "Memory Safety Without Garbage Collection for Embedded Applications"
                  Dinakar Dhurjati, Sumant Kowshik, Vikram Adve and Chris Lattner. Changes in directory llvm-www/safecode: index.html updated: 1.16 -> 1.17 --- Log message: *** empty log message *** --- Diffs of the changes: (+6 -1) index.html | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletion(-) Index: llvm-www/safecode/index.html diff -u llvm-www/safecode/index.html:1.16 llvm-www/safecode/index.html:1.17 --- llvm-www/safecode/index.html:1.16 Thu Nov 17 15:58:35 2005 +++ llvm-www/safecode/index.html Thu Nov 17 16:00:25 2005 @@ -20,6 +20,11 @@ enforcement of safety, using aggressive compiler techniques developed in this project.

                  + +

                  " +Enforcing Alias Analysis for Weakly Typed Languages : Technical Report +of PLDI Submission"

                  +

                  Project Members

                  Faculty

                  @@ -39,7 +44,7 @@

                  Publications

                    -
                  • Tech Report of PLDI submission

                    " Enforcing Alias Analysis for Weakly Typed Languages " +
                  • " Enforcing Alias Analysis for Weakly Typed Languages "
                    Dinakar dhurjati, Sumant Kowshik, and Vikram Adve. Technical Report #UIUCDCS-R-2005-2657, Computer Science Dept., University of From dhurjati at cs.uiuc.edu Thu Nov 17 16:02:02 2005 From: dhurjati at cs.uiuc.edu (Dinakar Dhurjati) Date: Thu, 17 Nov 2005 16:02:02 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/index.html Message-ID: <200511172202.QAA04636@zion.cs.uiuc.edu> Changes in directory llvm-www/safecode: index.html updated: 1.17 -> 1.18 --- Log message: *** empty log message *** --- Diffs of the changes: (+2 -2) index.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm-www/safecode/index.html diff -u llvm-www/safecode/index.html:1.17 llvm-www/safecode/index.html:1.18 --- llvm-www/safecode/index.html:1.17 Thu Nov 17 16:00:25 2005 +++ llvm-www/safecode/index.html Thu Nov 17 16:01:51 2005 @@ -21,9 +21,9 @@ project.

                    -

                    " +

                    Enforcing Alias Analysis for Weakly Typed Languages : Technical Report -of PLDI Submission"

                    +of PLDI Submission

                    Project Members

                    From dhurjati at cs.uiuc.edu Thu Nov 17 16:06:22 2005 From: dhurjati at cs.uiuc.edu (Dinakar Dhurjati) Date: Thu, 17 Nov 2005 16:06:22 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/index.html Message-ID: <200511172206.QAA04717@zion.cs.uiuc.edu> Changes in directory llvm-www/safecode: index.html updated: 1.18 -> 1.19 --- Log message: *** empty log message *** --- Diffs of the changes: (+2 -2) index.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm-www/safecode/index.html diff -u llvm-www/safecode/index.html:1.18 llvm-www/safecode/index.html:1.19 --- llvm-www/safecode/index.html:1.18 Thu Nov 17 16:01:51 2005 +++ llvm-www/safecode/index.html Thu Nov 17 16:06:11 2005 @@ -66,9 +66,9 @@ Sumant Kowshik, Dinakar Dhurjati, Vikram Adve. CASES 2002.
                  -

                  Implementation

                  + X = ADC Z, Y @@ -1111,7 +1154,7 @@ def ADC32ri : Ii32<0x81, MRM2r, (ops R32:$dst, R32:$src1, i32imm:$src2), "adc{l} {$src2, $dst|$dst, $src2}", []>; def ADC32ri8 : Ii8<0x83, MRM2r, (ops R32:$dst, R32:$src1, i8imm:$src2), - "adc{l} {$src2, $dst|$dst, $src2}">; + "adc{l} {$src2, $dst|$dst, $src2}", []>; let isTwoAddress = 0 in { def ADC32mr : I<0x11, MRMDestMem, (ops i32mem:$dst, R32:$src2), @@ -1119,7 +1162,7 @@ def ADC32mi : Ii32<0x81, MRM2m, (ops i32mem:$dst, i32imm:$src2), "adc{l} {$src2, $dst|$dst, $src2}", []>; def ADC32mi8 : Ii8<0x83, MRM2m, (ops i32mem:$dst, i8imm :$src2), - "adc{l} {$src2, $dst|$dst, $src2}">; + "adc{l} {$src2, $dst|$dst, $src2}", []>; } def SUB8rr : I<0x28, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2), @@ -1136,17 +1179,20 @@ "sub{l} {$src2, $dst|$dst, $src2}">; def SUB8ri : Ii8 <0x80, MRM5r, (ops R8:$dst, R8:$src1, i8imm:$src2), - "sub{b} {$src2, $dst|$dst, $src2}">; + "sub{b} {$src2, $dst|$dst, $src2}", + [(set R8:$dst, (sub R8:$src1, imm:$src2))]>; def SUB16ri : Ii16<0x81, MRM5r, (ops R16:$dst, R16:$src1, i16imm:$src2), "sub{w} {$src2, $dst|$dst, $src2}", [(set R16:$dst, (sub R16:$src1, imm:$src2))]>, OpSize; def SUB32ri : Ii32<0x81, MRM5r, (ops R32:$dst, R32:$src1, i32imm:$src2), "sub{l} {$src2, $dst|$dst, $src2}", [(set R32:$dst, (sub R32:$src1, imm:$src2))]>; -def SUB16ri8 : Ii8<0x83, MRM5r, (ops R16:$dst, R16:$src1, i8imm:$src2), - "sub{w} {$src2, $dst|$dst, $src2}">, OpSize; -def SUB32ri8 : Ii8<0x83, MRM5r, (ops R32:$dst, R32:$src1, i8imm:$src2), - "sub{l} {$src2, $dst|$dst, $src2}">; +def SUB16ri8 : Ii8<0x83, MRM5r, (ops R16:$dst, R16:$src1, i16i8imm:$src2), + "sub{w} {$src2, $dst|$dst, $src2}", + [(set R16:$dst, (sub R16:$src1, immSExt8:$src2))]>, OpSize; +def SUB32ri8 : Ii8<0x83, MRM5r, (ops R32:$dst, R32:$src1, i32i8imm:$src2), + "sub{l} {$src2, $dst|$dst, $src2}", + [(set R32:$dst, (sub R32:$src1, immSExt8:$src2))]>; let isTwoAddress = 0 in { def SUB8mr : I<0x28, MRMDestMem, (ops i8mem :$dst, R8 :$src2), "sub{b} {$src2, $dst|$dst, $src2}">; @@ -1155,15 +1201,15 @@ def SUB32mr : I<0x29, MRMDestMem, (ops i32mem:$dst, R32:$src2), "sub{l} {$src2, $dst|$dst, $src2}">; def SUB8mi : Ii8<0x80, MRM5m, (ops i8mem :$dst, i8imm:$src2), - "sub{b} {$src2, $dst|$dst, $src2}">; + "sub{b} {$src2, $dst|$dst, $src2}", []>; def SUB16mi : Ii16<0x81, MRM5m, (ops i16mem:$dst, i16imm:$src2), "sub{w} {$src2, $dst|$dst, $src2}", []>, OpSize; def SUB32mi : Ii32<0x81, MRM5m, (ops i32mem:$dst, i32imm:$src2), "sub{l} {$src2, $dst|$dst, $src2}", []>; def SUB16mi8 : Ii8<0x83, MRM5m, (ops i16mem:$dst, i8imm :$src2), - "sub{w} {$src2, $dst|$dst, $src2}">, OpSize; + "sub{w} {$src2, $dst|$dst, $src2}", []>, OpSize; def SUB32mi8 : Ii8<0x83, MRM5m, (ops i32mem:$dst, i8imm :$src2), - "sub{l} {$src2, $dst|$dst, $src2}">; + "sub{l} {$src2, $dst|$dst, $src2}", []>; } def SBB32rr : I<0x19, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2), @@ -1179,12 +1225,12 @@ def SBB32mi : Ii32<0x81, MRM3m, (ops i32mem:$dst, i32imm:$src2), "sbb{l} {$src2, $dst|$dst, $src2}", []>; def SBB16mi8 : Ii8<0x83, MRM3m, (ops i16mem:$dst, i8imm :$src2), - "sbb{w} {$src2, $dst|$dst, $src2}">, OpSize; + "sbb{w} {$src2, $dst|$dst, $src2}", []>, OpSize; def SBB32mi8 : Ii8<0x83, MRM3m, (ops i32mem:$dst, i8imm :$src2), - "sbb{l} {$src2, $dst|$dst, $src2}">; + "sbb{l} {$src2, $dst|$dst, $src2}", []>; } def SBB8ri : Ii8<0x80, MRM3r, (ops R8:$dst, R8:$src1, i8imm:$src2), - "sbb{b} {$src2, $dst|$dst, $src2}">; + "sbb{b} {$src2, $dst|$dst, $src2}", []>; def SBB16ri : Ii16<0x81, MRM3r, (ops R16:$dst, R16:$src1, i16imm:$src2), "sbb{w} {$src2, $dst|$dst, $src2}", []>, OpSize; @@ -1194,9 +1240,9 @@ "sbb{l} {$src2, $dst|$dst, $src2}", []>; def SBB16ri8 : Ii8<0x83, MRM3r, (ops R16:$dst, R16:$src1, i8imm:$src2), - "sbb{w} {$src2, $dst|$dst, $src2}">, OpSize; + "sbb{w} {$src2, $dst|$dst, $src2}", []>, OpSize; def SBB32ri8 : Ii8<0x83, MRM3r, (ops R32:$dst, R32:$src1, i8imm:$src2), - "sbb{l} {$src2, $dst|$dst, $src2}">; + "sbb{l} {$src2, $dst|$dst, $src2}", []>; let isCommutable = 1 in { // X = IMUL Y, Z --> X = IMUL Z, Y def IMUL16rr : I<0xAF, MRMSrcReg, (ops R16:$dst, R16:$src1, R16:$src2), @@ -1222,11 +1268,13 @@ "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}", [(set R32:$dst, (mul R32:$src1, imm:$src2))]>; def IMUL16rri8 : Ii8<0x6B, MRMSrcReg, // R16 = R16*I8 - (ops R16:$dst, R16:$src1, i8imm:$src2), - "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}">, OpSize; + (ops R16:$dst, R16:$src1, i16i8imm:$src2), + "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}", + [(set R16:$dst, (mul R16:$src1, immSExt8:$src2))]>, OpSize; def IMUL32rri8 : Ii8<0x6B, MRMSrcReg, // R32 = R32*I8 - (ops R32:$dst, R32:$src1, i8imm:$src2), - "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}">; + (ops R32:$dst, R32:$src1, i32i8imm:$src2), + "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}", + [(set R32:$dst, (mul R32:$src1, immSExt8:$src2))]>; def IMUL16rmi : Ii16<0x69, MRMSrcMem, // R16 = [mem16]*I16 (ops R32:$dst, i16mem:$src1, i16imm:$src2), @@ -1236,10 +1284,10 @@ "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}", []>; def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem, // R16 = [mem16]*I8 (ops R32:$dst, i16mem:$src1, i8imm :$src2), - "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}">, OpSize; + "imul{w} {$src2, $src1, $dst|$dst, $src1, $src2}", []>, OpSize; def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem, // R32 = [mem32]*I8 (ops R32:$dst, i32mem:$src1, i8imm: $src2), - "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}">; + "imul{l} {$src2, $src1, $dst|$dst, $src1, $src2}", []>; //===----------------------------------------------------------------------===// // Test instructions are just like AND, except they don't generate a result. @@ -1267,7 +1315,7 @@ def TEST8ri : Ii8 <0xF6, MRM0r, // flags = R8 & imm8 (ops R8:$src1, i8imm:$src2), - "test{b} {$src2, $src1|$src1, $src2}">; + "test{b} {$src2, $src1|$src1, $src2}", []>; def TEST16ri : Ii16<0xF7, MRM0r, // flags = R16 & imm16 (ops R16:$src1, i16imm:$src2), "test{w} {$src2, $src1|$src1, $src2}", []>, OpSize; @@ -1276,7 +1324,7 @@ "test{l} {$src2, $src1|$src1, $src2}", []>; def TEST8mi : Ii8 <0xF6, MRM0m, // flags = [mem8] & imm8 (ops i32mem:$src1, i8imm:$src2), - "test{b} {$src2, $src1|$src1, $src2}">; + "test{b} {$src2, $src1|$src1, $src2}", []>; def TEST16mi : Ii16<0xF7, MRM0m, // flags = [mem16] & imm16 (ops i16mem:$src1, i16imm:$src2), "test{w} {$src2, $src1|$src1, $src2}", []>, OpSize; @@ -1377,7 +1425,7 @@ "cmp{l} {$src2, $src1|$src1, $src2}">; def CMP8ri : Ii8<0x80, MRM7r, (ops R16:$src1, i8imm:$src2), - "cmp{b} {$src2, $src1|$src1, $src2}">; + "cmp{b} {$src2, $src1|$src1, $src2}", []>; def CMP16ri : Ii16<0x81, MRM7r, (ops R16:$src1, i16imm:$src2), "cmp{w} {$src2, $src1|$src1, $src2}", []>, OpSize; @@ -1386,7 +1434,7 @@ "cmp{l} {$src2, $src1|$src1, $src2}", []>; def CMP8mi : Ii8 <0x80, MRM7m, (ops i8mem :$src1, i8imm :$src2), - "cmp{b} {$src2, $src1|$src1, $src2}">; + "cmp{b} {$src2, $src1|$src1, $src2}", []>; def CMP16mi : Ii16<0x81, MRM7m, (ops i16mem:$src1, i16imm:$src2), "cmp{w} {$src2, $src1|$src1, $src2}", []>, OpSize; From lattner at cs.uiuc.edu Fri Nov 18 01:27:45 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 18 Nov 2005 01:27:45 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/Dominators.h Message-ID: <200511180727.BAA07972@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: Dominators.h updated: 1.49 -> 1.50 --- Log message: Fix the dominates method to return true if the two nodes are the same. Add a new properlyDominates method to do what the old one did. --- Diffs of the changes: (+12 -4) Dominators.h | 16 ++++++++++++---- 1 files changed, 12 insertions(+), 4 deletions(-) Index: llvm/include/llvm/Analysis/Dominators.h diff -u llvm/include/llvm/Analysis/Dominators.h:1.49 llvm/include/llvm/Analysis/Dominators.h:1.50 --- llvm/include/llvm/Analysis/Dominators.h:1.49 Thu Apr 21 15:16:31 2005 +++ llvm/include/llvm/Analysis/Dominators.h Fri Nov 18 01:27:33 2005 @@ -306,16 +306,24 @@ inline Node *getIDom() const { return IDom; } inline const std::vector &getChildren() const { return Children; } - /// dominates - Returns true iff this dominates N. Note that this is not a - /// constant time operation! + /// properlyDominates - Returns true iff this dominates N and this != N. + /// Note that this is not a constant time operation! /// - inline bool dominates(const Node *N) const { + bool properlyDominates(const Node *N) const { const Node *IDom; while ((IDom = N->getIDom()) != 0 && IDom != this) - N = IDom; // Walk up the tree + N = IDom; // Walk up the tree return IDom != 0; } + /// dominates - Returns true iff this dominates N. Note that this is not a + /// constant time operation! + /// + inline bool dominates(const Node *N) const { + if (N == this) return true; // A node trivially dominates itself. + return properlyDominates(N); + } + private: inline Node(BasicBlock *BB, Node *iDom) : TheBB(BB), IDom(iDom) {} inline Node *addChild(Node *C) { Children.push_back(C); return C; } From lattner at cs.uiuc.edu Fri Nov 18 01:28:05 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 18 Nov 2005 01:28:05 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Dominators.cpp Message-ID: <200511180728.BAA08030@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Dominators.cpp updated: 1.63 -> 1.64 --- Log message: This requires proper dominance --- Diffs of the changes: (+1 -1) Dominators.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/VMCore/Dominators.cpp diff -u llvm/lib/VMCore/Dominators.cpp:1.63 llvm/lib/VMCore/Dominators.cpp:1.64 --- llvm/lib/VMCore/Dominators.cpp:1.63 Mon Apr 25 15:50:33 2005 +++ llvm/lib/VMCore/Dominators.cpp Fri Nov 18 01:27:53 2005 @@ -452,7 +452,7 @@ DomSetType::const_iterator CDFI = ChildDF.begin(), CDFE = ChildDF.end(); for (; CDFI != CDFE; ++CDFI) { - if (!Node->dominates(DT[*CDFI])) + if (!Node->properlyDominates(DT[*CDFI])) S.insert(*CDFI); } } From lattner at cs.uiuc.edu Fri Nov 18 01:28:38 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 18 Nov 2005 01:28:38 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/PostDominators.cpp Message-ID: <200511180728.BAA08109@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: PostDominators.cpp updated: 1.52 -> 1.53 --- Log message: post-dom-frontiers requires proper post-dominance --- Diffs of the changes: (+1 -1) PostDominators.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Analysis/PostDominators.cpp diff -u llvm/lib/Analysis/PostDominators.cpp:1.52 llvm/lib/Analysis/PostDominators.cpp:1.53 --- llvm/lib/Analysis/PostDominators.cpp:1.52 Thu Apr 21 22:54:55 2005 +++ llvm/lib/Analysis/PostDominators.cpp Fri Nov 18 01:28:26 2005 @@ -239,7 +239,7 @@ DomSetType::const_iterator CDFI = ChildDF.begin(), CDFE = ChildDF.end(); for (; CDFI != CDFE; ++CDFI) { - if (!Node->dominates(DT[*CDFI])) + if (!Node->properlyDominates(DT[*CDFI])) S.insert(*CDFI); } } From lattner at cs.uiuc.edu Fri Nov 18 01:29:56 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 18 Nov 2005 01:29:56 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Message-ID: <200511180729.BAA08142@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: PromoteMemoryToRegister.cpp updated: 1.80 -> 1.81 --- Log message: This needs proper dominance --- Diffs of the changes: (+14 -5) PromoteMemoryToRegister.cpp | 19 ++++++++++++++----- 1 files changed, 14 insertions(+), 5 deletions(-) Index: llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp diff -u llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.80 llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.81 --- llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.80 Thu Aug 4 19:57:45 2005 +++ llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Fri Nov 18 01:29:44 2005 @@ -96,12 +96,18 @@ void run(); - /// dominates - Return true if I1 dominates I2 using the DominatorTree. + /// properlyDominates - Return true if I1 properly dominates I2. /// - bool dominates(Instruction *I1, Instruction *I2) const { + bool properlyDominates(Instruction *I1, Instruction *I2) const { if (InvokeInst *II = dyn_cast(I1)) I1 = II->getNormalDest()->begin(); - return DT[I1->getParent()]->dominates(DT[I2->getParent()]); + return DT[I1->getParent()]->properlyDominates(DT[I2->getParent()]); + } + + /// dominates - Return true if BB1 dominates BB2 using the DominatorTree. + /// + bool dominates(BasicBlock *BB1, BasicBlock *BB2) const { + return DT[BB1]->dominates(DT[BB2]); } private: @@ -168,7 +174,8 @@ // Remember the basic blocks which define new values for the alloca DefiningBlocks.push_back(SI->getParent()); AllocaPointerVal = SI->getOperand(0); - } else if (LoadInst *LI = dyn_cast(User)) { + } else { + LoadInst *LI = cast(User); // Otherwise it must be a load instruction, keep track of variable reads UsingBlocks.push_back(LI->getParent()); AllocaPointerVal = LI; @@ -194,6 +201,7 @@ continue; } + if (AST) PointerAllocaValues[AllocaNum] = AllocaPointerVal; @@ -348,7 +356,8 @@ for (unsigned i = 0, e = PNs.size(); i != e; ++i) if (PNs[i]) { if (Value *V = PNs[i]->hasConstantValue(true)) { - if (!isa(V) || dominates(cast(V), PNs[i])) { + if (!isa(V) || + properlyDominates(cast(V), PNs[i])) { if (AST && isa(PNs[i]->getType())) AST->deleteValue(PNs[i]); PNs[i]->replaceAllUsesWith(V); From lattner at cs.uiuc.edu Fri Nov 18 01:31:54 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 18 Nov 2005 01:31:54 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Message-ID: <200511180731.BAA08209@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: PromoteMemoryToRegister.cpp updated: 1.81 -> 1.82 --- Log message: Implement a refinement to the mem2reg algorithm for cases where an alloca has a single def. In this case, look for uses that are dominated by the def and attempt to rewrite them to directly use the stored value. This speeds up mem2reg on these values and reduces the number of phi nodes inserted. This should address PR665: http://llvm.cs.uiuc.edu/PR665 . --- Diffs of the changes: (+55 -0) PromoteMemoryToRegister.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 55 insertions(+) Index: llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp diff -u llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.81 llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.82 --- llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.81 Fri Nov 18 01:29:44 2005 +++ llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Fri Nov 18 01:31:42 2005 @@ -161,6 +161,7 @@ std::vector DefiningBlocks; std::vector UsingBlocks; + StoreInst *OnlyStore = 0; BasicBlock *OnlyBlock = 0; bool OnlyUsedInOneBlock = true; @@ -174,6 +175,7 @@ // Remember the basic blocks which define new values for the alloca DefiningBlocks.push_back(SI->getParent()); AllocaPointerVal = SI->getOperand(0); + OnlyStore = SI; } else { LoadInst *LI = cast(User); // Otherwise it must be a load instruction, keep track of variable reads @@ -201,6 +203,59 @@ continue; } + // If there is only a single store to this value, replace any loads of + // it that are directly dominated by the definition with the value stored. + if (DefiningBlocks.size() == 1) { + // Be aware of loads before the store. + std::set ProcessedBlocks; + for (unsigned i = 0, e = UsingBlocks.size(); i != e; ++i) + // If the store dominates the block and if we haven't processed it yet, + // do so now. + if (dominates(OnlyStore->getParent(), UsingBlocks[i])) + if (ProcessedBlocks.insert(UsingBlocks[i]).second) { + BasicBlock *UseBlock = UsingBlocks[i]; + + // If the use and store are in the same block, do a quick scan to + // verify that there are no uses before the store. + if (UseBlock == OnlyStore->getParent()) { + BasicBlock::iterator I = UseBlock->begin(); + for (; &*I != OnlyStore; ++I) { // scan block for store. + if (isa(I) && I->getOperand(0) == AI) + break; + } + if (&*I != OnlyStore) break; // Do not handle this case. + } + + // Otherwise, if this is a different block or if all uses happen + // after the store, do a simple linear scan to replace loads with + // the stored value. + for (BasicBlock::iterator I = UseBlock->begin(),E = UseBlock->end(); + I != E; ) { + if (LoadInst *LI = dyn_cast(I++)) { + if (LI->getOperand(0) == AI) { + LI->replaceAllUsesWith(OnlyStore->getOperand(0)); + if (AST && isa(LI->getType())) + AST->deleteValue(LI); + LI->eraseFromParent(); + } + } + } + + // Finally, remove this block from the UsingBlock set. + UsingBlocks[i] = UsingBlocks.back(); + --i; --e; + } + + // Finally, after the scan, check to see if the store is all that is left. + if (UsingBlocks.empty()) { + // The alloca has been processed, move on. + Allocas[AllocaNum] = Allocas.back(); + Allocas.pop_back(); + --AllocaNum; + continue; + } + } + if (AST) PointerAllocaValues[AllocaNum] = AllocaPointerVal; From natebegeman at mac.com Fri Nov 18 01:43:07 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 18 Nov 2005 01:43:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200511180743.BAA08255@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.100 -> 1.101 --- Log message: Split out the shift code from visitBinary. --- Diffs of the changes: (+14 -7) SelectionDAGISel.cpp | 21 ++++++++++++++------- 1 files changed, 14 insertions(+), 7 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.100 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.101 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.100 Wed Nov 16 01:22:30 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Nov 18 01:42:56 2005 @@ -347,7 +347,8 @@ void visitUnwind(UnwindInst &I) { assert(0 && "TODO"); } // - void visitBinary(User &I, unsigned Opcode, bool isShift = false); + void visitBinary(User &I, unsigned Opcode); + void visitShift(User &I, unsigned Opcode); void visitAdd(User &I) { visitBinary(I, I.getType()->isFloatingPoint() ? ISD::FADD : ISD::ADD); } @@ -380,9 +381,9 @@ void visitAnd(User &I) { visitBinary(I, ISD::AND); } void visitOr (User &I) { visitBinary(I, ISD::OR); } void visitXor(User &I) { visitBinary(I, ISD::XOR); } - void visitShl(User &I) { visitBinary(I, ISD::SHL, true); } - void visitShr(User &I) { - visitBinary(I, I.getType()->isUnsigned() ? ISD::SRL : ISD::SRA, true); + void visitShl(User &I) { visitShift(I, ISD::SHL); } + void visitShr(User &I) { + visitShift(I, I.getType()->isUnsigned() ? ISD::SRL : ISD::SRA); } void visitSetCC(User &I, ISD::CondCode SignedOpc, ISD::CondCode UnsignedOpc); @@ -520,13 +521,19 @@ } } -void SelectionDAGLowering::visitBinary(User &I, unsigned Opcode, bool isShift) { +void SelectionDAGLowering::visitBinary(User &I, unsigned Opcode) { SDOperand Op1 = getValue(I.getOperand(0)); SDOperand Op2 = getValue(I.getOperand(1)); - if (isShift) - Op2 = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), Op2); + setValue(&I, DAG.getNode(Opcode, Op1.getValueType(), Op1, Op2)); +} +void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) { + SDOperand Op1 = getValue(I.getOperand(0)); + SDOperand Op2 = getValue(I.getOperand(1)); + + Op2 = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), Op2); + setValue(&I, DAG.getNode(Opcode, Op1.getValueType(), Op1, Op2)); } From alenhar2 at cs.uiuc.edu Fri Nov 18 07:57:22 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Fri, 18 Nov 2005 07:57:22 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaTargetMachine.cpp Message-ID: <200511181357.HAA08086@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaTargetMachine.cpp updated: 1.18 -> 1.19 --- Log message: prevent latent switch creation --- Diffs of the changes: (+2 -2) AlphaTargetMachine.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/Alpha/AlphaTargetMachine.cpp diff -u llvm/lib/Target/Alpha/AlphaTargetMachine.cpp:1.18 llvm/lib/Target/Alpha/AlphaTargetMachine.cpp:1.19 --- llvm/lib/Target/Alpha/AlphaTargetMachine.cpp:1.18 Sat Nov 12 19:45:23 2005 +++ llvm/lib/Target/Alpha/AlphaTargetMachine.cpp Fri Nov 18 07:57:03 2005 @@ -79,7 +79,9 @@ if (FileType != TargetMachine::AssemblyFile) return true; PM.add(createLoopStrengthReducePass()); + PM.add(createCFGSimplificationPass()); + // FIXME: Implement efficient support for garbage collection intrinsics. PM.add(createLowerGCPass()); @@ -92,8 +94,6 @@ // Make sure that no unreachable blocks are instruction selected. PM.add(createUnreachableBlockEliminationPass()); - PM.add(createCFGSimplificationPass()); - if (EnableAlphaDAG) PM.add(createAlphaISelDag(*this)); else From lattner at cs.uiuc.edu Fri Nov 18 12:30:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 18 Nov 2005 12:30:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <200511181830.MAA09835@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: IndVarSimplify.cpp updated: 1.81 -> 1.82 --- Log message: Fix a crash building 176.gcc due to my recent patch, which only fixed half the problem. --- Diffs of the changes: (+1 -1) IndVarSimplify.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp diff -u llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.81 llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.82 --- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.81 Thu Nov 17 13:35:42 2005 +++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Fri Nov 18 12:30:47 2005 @@ -161,7 +161,7 @@ assert(NumOps > 1 && "CE folding didn't work!"); if (CE->getOperand(NumOps-1)->isNullValue()) { // Check to make sure the last index really is an array index. - gep_type_iterator GTI = gep_type_begin(GEPI); + gep_type_iterator GTI = gep_type_begin(CE); for (unsigned i = 1, e = CE->getNumOperands()-1; i != e; ++i, ++GTI) /*empty*/; From lattner at cs.uiuc.edu Fri Nov 18 13:38:27 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 18 Nov 2005 13:38:27 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/IndVarsSimplify/2005-11-18-Crash.ll Message-ID: <200511181938.NAA10191@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/IndVarsSimplify: 2005-11-18-Crash.ll added (r1.1) --- Log message: testcase for recent indvars patches --- Diffs of the changes: (+18 -0) 2005-11-18-Crash.ll | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+) Index: llvm/test/Regression/Transforms/IndVarsSimplify/2005-11-18-Crash.ll diff -c /dev/null llvm/test/Regression/Transforms/IndVarsSimplify/2005-11-18-Crash.ll:1.1 *** /dev/null Fri Nov 18 13:38:25 2005 --- llvm/test/Regression/Transforms/IndVarsSimplify/2005-11-18-Crash.ll Fri Nov 18 13:38:15 2005 *************** *** 0 **** --- 1,18 ---- + ; RUN: llvm-as < %s | opt -indvars -disable-output + + %fixtab = external global [29 x [29 x [2 x uint]]] ; <[29 x [29 x [2 x uint]]]*> [#uses=1] + + implementation ; Functions: + + void %init_optabs() { + entry: + br label %no_exit.0 + + no_exit.0: ; preds = %no_exit.0, %entry + %p.0.0 = phi uint* [ getelementptr ([29 x [29 x [2 x uint]]]* %fixtab, int 0, int 0, int 0, int 0), %entry ], [ %inc.0, %no_exit.0 ] ; [#uses=1] + %inc.0 = getelementptr uint* %p.0.0, int 1 ; [#uses=1] + br bool false, label %no_exit.0, label %no_exit.1 + + no_exit.1: ; preds = %no_exit.0 + ret void + } From dhurjati at cs.uiuc.edu Fri Nov 18 16:21:46 2005 From: dhurjati at cs.uiuc.edu (Dinakar Dhurjati) Date: Fri, 18 Nov 2005 16:21:46 -0600 Subject: [llvm-commits] CVS: llvm-www/safecode/index.html Message-ID: <200511182221.QAA10921@zion.cs.uiuc.edu> Changes in directory llvm-www/safecode: index.html updated: 1.23 -> 1.24 --- Log message: Removed download section from safecode --- Diffs of the changes: (+0 -4) index.html | 4 ---- 1 files changed, 4 deletions(-) Index: llvm-www/safecode/index.html diff -u llvm-www/safecode/index.html:1.23 llvm-www/safecode/index.html:1.24 --- llvm-www/safecode/index.html:1.23 Thu Nov 17 16:10:14 2005 +++ llvm-www/safecode/index.html Fri Nov 18 16:21:34 2005 @@ -67,10 +67,6 @@ Sumant Kowshik, Dinakar Dhurjati, Vikram Adve. CASES 2002.
                -

                Download

                - -

                Not in public domain for now. Check this page later.

                -

                Funding

                This project is sponsored by the NSF Embedded Systems program under award From natebegeman at mac.com Fri Nov 18 18:36:50 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 18 Nov 2005 18:36:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/ValueTypes.cpp Message-ID: <200511190036.SAA11542@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: ValueTypes.cpp updated: 1.4 -> 1.5 --- Log message: Teach LLVM how to scalarize packed types. Currently, this only works on packed types with an element count of 1, although more generic support is coming. This allows LLVM to turn the following code: void %foo(<1 x float> * %a) { entry: %tmp1 = load <1 x float> * %a; %tmp2 = add <1 x float> %tmp1, %tmp1 store <1 x float> %tmp2, <1 x float> *%a ret void } Into: _foo: lfs f0, 0(r3) fadds f0, f0, f0 stfs f0, 0(r3) blr --- Diffs of the changes: (+1 -0) ValueTypes.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/CodeGen/ValueTypes.cpp diff -u llvm/lib/CodeGen/ValueTypes.cpp:1.4 llvm/lib/CodeGen/ValueTypes.cpp:1.5 --- llvm/lib/CodeGen/ValueTypes.cpp:1.4 Thu Aug 25 12:59:23 2005 +++ llvm/lib/CodeGen/ValueTypes.cpp Fri Nov 18 18:36:38 2005 @@ -33,6 +33,7 @@ case MVT::isVoid:return "isVoid"; case MVT::Other: return "ch"; case MVT::Flag: return "flag"; + case MVT::Vector:return "vec"; } } From natebegeman at mac.com Fri Nov 18 18:36:50 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 18 Nov 2005 18:36:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAG.cpp SelectionDAGISel.cpp Message-ID: <200511190036.SAA11534@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.209 -> 1.210 SelectionDAG.cpp updated: 1.212 -> 1.213 SelectionDAGISel.cpp updated: 1.101 -> 1.102 --- Log message: Teach LLVM how to scalarize packed types. Currently, this only works on packed types with an element count of 1, although more generic support is coming. This allows LLVM to turn the following code: void %foo(<1 x float> * %a) { entry: %tmp1 = load <1 x float> * %a; %tmp2 = add <1 x float> %tmp1, %tmp1 store <1 x float> %tmp2, <1 x float> *%a ret void } Into: _foo: lfs f0, 0(r3) fadds f0, f0, f0 stfs f0, 0(r3) blr --- Diffs of the changes: (+110 -33) LegalizeDAG.cpp | 53 ++++++++++++++++++++++++++++++++++++++- SelectionDAG.cpp | 21 +++++++++++++++ SelectionDAGISel.cpp | 69 +++++++++++++++++++++++++++------------------------ 3 files changed, 110 insertions(+), 33 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.209 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.210 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.209 Thu Nov 17 00:41:44 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Nov 18 18:36:38 2005 @@ -149,6 +149,15 @@ }; } +static unsigned scalarizedOpcode(unsigned VecOp, MVT::ValueType VT) { + switch (VecOp) { + default: assert(0 && "Don't know how to scalarize this opcode!"); + break; + case ISD::VADD: return MVT::isInteger(VT) ? ISD::ADD : ISD::FADD; + case ISD::VSUB: return MVT::isInteger(VT) ? ISD::SUB : ISD::FSUB; + case ISD::VMUL: return MVT::isInteger(VT) ? ISD::MUL : ISD::FMUL; + } +} SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag) : TLI(dag.getTargetLoweringInfo()), DAG(dag), @@ -914,7 +923,27 @@ AddLegalizedOperand(SDOperand(Node, 0), Result); AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); return Result.getValue(Op.ResNo); - + + case ISD::VLOAD: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. + + // If we just have one element, scalarize the result. Otherwise, check to + // see if we support this operation on this type at this width. If not, + // split the vector in half and try again. + if (1 == cast(Node->getOperand(2))->getValue()) { + MVT::ValueType SVT = cast(Node->getOperand(3))->getVT(); + Result = LegalizeOp(DAG.getLoad(SVT, Tmp1, Tmp2, Node->getOperand(4))); + } else { + assert(0 && "Expand case for vectors unimplemented"); + } + + // Since loads produce two values, make sure to remember that we legalized + // both of them. + AddLegalizedOperand(SDOperand(Node, 0), Result); + AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); + return Result.getValue(Op.ResNo); + case ISD::EXTLOAD: case ISD::SEXTLOAD: case ISD::ZEXTLOAD: { @@ -1654,6 +1683,28 @@ Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1,Tmp2); break; + // Vector binary operators + case ISD::VADD: + case ISD::VSUB: + case ISD::VMUL: { + Tmp1 = Node->getOperand(0); // Element Count + Tmp2 = Node->getOperand(1); // Element Type + + // If we just have one element, scalarize the result. Otherwise, check to + // see if we support this operation on this type at this width. If not, + // split the vector in half and try again. + if (1 == cast(Tmp1)->getValue()) { + MVT::ValueType SVT = cast(Tmp2)->getVT(); + + Result = DAG.getNode(scalarizedOpcode(Node->getOpcode(), SVT), SVT, + LegalizeOp(Node->getOperand(2)), + LegalizeOp(Node->getOperand(3))); + } else { + assert(0 && "Expand case for vectors unimplemented"); + } + break; + } + case ISD::BUILD_PAIR: { MVT::ValueType PairTy = Node->getValueType(0); // TODO: handle the case where the Lo and Hi operands are not of legal type Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.212 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.213 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.212 Fri Nov 11 10:46:18 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Nov 18 18:36:38 2005 @@ -1092,6 +1092,23 @@ return SDOperand(N, 0); } +SDOperand SelectionDAG::getVecLoad(unsigned Count, MVT::ValueType EVT, + SDOperand Chain, SDOperand Ptr, + SDOperand SV) { + SDNode *&N = Loads[std::make_pair(Ptr, std::make_pair(Chain, EVT))]; + if (N) return SDOperand(N, 0); + std::vector Ops; + Ops.reserve(5); + Ops.push_back(Chain); + Ops.push_back(Ptr); + Ops.push_back(getConstant(Count, MVT::i32)); + Ops.push_back(getValueType(EVT)); + Ops.push_back(SV); + std::vector VTs; + VTs.reserve(2); + VTs.push_back(EVT); VTs.push_back(MVT::Other); // Add token chain. + return getNode(ISD::VLOAD, VTs, Ops); +} SDOperand SelectionDAG::getExtLoad(unsigned Opcode, MVT::ValueType VT, SDOperand Chain, SDOperand Ptr, SDOperand SV, @@ -1677,6 +1694,9 @@ case ISD::FMUL: return "fmul"; case ISD::FDIV: return "fdiv"; case ISD::FREM: return "frem"; + case ISD::VADD: return "vadd"; + case ISD::VSUB: return "vsub"; + case ISD::VMUL: return "vmul"; case ISD::SETCC: return "setcc"; case ISD::SELECT: return "select"; @@ -1717,6 +1737,7 @@ // Other operators case ISD::LOAD: return "load"; case ISD::STORE: return "store"; + case ISD::VLOAD: return "vload"; case ISD::EXTLOAD: return "extload"; case ISD::SEXTLOAD: return "sextload"; case ISD::ZEXTLOAD: return "zextload"; Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.101 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.102 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.101 Fri Nov 18 01:42:56 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Nov 18 18:36:38 2005 @@ -347,40 +347,26 @@ void visitUnwind(UnwindInst &I) { assert(0 && "TODO"); } // - void visitBinary(User &I, unsigned Opcode); + void visitBinary(User &I, unsigned IntOp, unsigned FPOp, unsigned VecOp); void visitShift(User &I, unsigned Opcode); - void visitAdd(User &I) { - visitBinary(I, I.getType()->isFloatingPoint() ? ISD::FADD : ISD::ADD); + void visitAdd(User &I) { + visitBinary(I, ISD::ADD, ISD::FADD, ISD::VADD); } void visitSub(User &I); - void visitMul(User &I) { - visitBinary(I, I.getType()->isFloatingPoint() ? ISD::FMUL : ISD::MUL); + void visitMul(User &I) { + visitBinary(I, ISD::MUL, ISD::FMUL, ISD::VMUL); } void visitDiv(User &I) { - unsigned Opc; const Type *Ty = I.getType(); - if (Ty->isFloatingPoint()) - Opc = ISD::FDIV; - else if (Ty->isUnsigned()) - Opc = ISD::UDIV; - else - Opc = ISD::SDIV; - visitBinary(I, Opc); + visitBinary(I, Ty->isSigned() ? ISD::SDIV : ISD::UDIV, ISD::FDIV, 0); } void visitRem(User &I) { - unsigned Opc; const Type *Ty = I.getType(); - if (Ty->isFloatingPoint()) - Opc = ISD::FREM; - else if (Ty->isUnsigned()) - Opc = ISD::UREM; - else - Opc = ISD::SREM; - visitBinary(I, Opc); + visitBinary(I, Ty->isSigned() ? ISD::SREM : ISD::UREM, ISD::FREM, 0); } - void visitAnd(User &I) { visitBinary(I, ISD::AND); } - void visitOr (User &I) { visitBinary(I, ISD::OR); } - void visitXor(User &I) { visitBinary(I, ISD::XOR); } + void visitAnd(User &I) { visitBinary(I, ISD::AND, 0, 0); } + void visitOr (User &I) { visitBinary(I, ISD::OR, 0, 0); } + void visitXor(User &I) { visitBinary(I, ISD::XOR, 0, 0); } void visitShl(User &I) { visitShift(I, ISD::SHL); } void visitShr(User &I) { visitShift(I, I.getType()->isUnsigned() ? ISD::SRL : ISD::SRA); @@ -515,17 +501,26 @@ setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2)); return; } - visitBinary(I, ISD::FSUB); - } else { - visitBinary(I, ISD::SUB); } + visitBinary(I, ISD::SUB, ISD::FSUB, ISD::VSUB); } -void SelectionDAGLowering::visitBinary(User &I, unsigned Opcode) { +void SelectionDAGLowering::visitBinary(User &I, unsigned IntOp, unsigned FPOp, + unsigned VecOp) { + const Type *Ty = I.getType(); SDOperand Op1 = getValue(I.getOperand(0)); SDOperand Op2 = getValue(I.getOperand(1)); - setValue(&I, DAG.getNode(Opcode, Op1.getValueType(), Op1, Op2)); + if (Ty->isInteger()) { + setValue(&I, DAG.getNode(IntOp, Op1.getValueType(), Op1, Op2)); + } else if (Ty->isFloatingPoint()) { + setValue(&I, DAG.getNode(FPOp, Op1.getValueType(), Op1, Op2)); + } else { + const PackedType *PTy = cast(Ty); + SDOperand Num = DAG.getConstant(PTy->getNumElements(), MVT::i32); + SDOperand Typ = DAG.getValueType(TLI.getValueType(PTy->getElementType())); + setValue(&I, DAG.getNode(VecOp, Op1.getValueType(), Num, Typ, Op1, Op2)); + } } void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) { @@ -725,9 +720,19 @@ // Do not serialize non-volatile loads against each other. Root = DAG.getRoot(); } - - SDOperand L = DAG.getLoad(TLI.getValueType(I.getType()), Root, Ptr, - DAG.getSrcValue(I.getOperand(0))); + + const Type *Ty = I.getType(); + SDOperand L; + + if (Type::PackedTyID == Ty->getTypeID()) { + const PackedType *PTy = cast(Ty); + L = DAG.getVecLoad(PTy->getNumElements(), + TLI.getValueType(PTy->getElementType()), Root, Ptr, + DAG.getSrcValue(I.getOperand(0))); + } else { + L = DAG.getLoad(TLI.getValueType(Ty), Root, Ptr, + DAG.getSrcValue(I.getOperand(0))); + } setValue(&I, L); if (I.isVolatile()) From natebegeman at mac.com Fri Nov 18 18:36:50 2005 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 18 Nov 2005 18:36:50 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h SelectionDAGNodes.h Message-ID: <200511190036.SAA11541@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.68 -> 1.69 SelectionDAGNodes.h updated: 1.75 -> 1.76 --- Log message: Teach LLVM how to scalarize packed types. Currently, this only works on packed types with an element count of 1, although more generic support is coming. This allows LLVM to turn the following code: void %foo(<1 x float> * %a) { entry: %tmp1 = load <1 x float> * %a; %tmp2 = add <1 x float> %tmp1, %tmp1 store <1 x float> %tmp2, <1 x float> *%a ret void } Into: _foo: lfs f0, 0(r3) fadds f0, f0, f0 stfs f0, 0(r3) blr --- Diffs of the changes: (+13 -1) SelectionDAG.h | 2 ++ SelectionDAGNodes.h | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.68 llvm/include/llvm/CodeGen/SelectionDAG.h:1.69 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.68 Wed Nov 9 17:46:43 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Fri Nov 18 18:36:38 2005 @@ -257,6 +257,8 @@ /// SDOperand getLoad(MVT::ValueType VT, SDOperand Chain, SDOperand Ptr, SDOperand SV); + SDOperand getVecLoad(unsigned Count, MVT::ValueType VT, SDOperand Chain, + SDOperand Ptr, SDOperand SV); SDOperand getExtLoad(unsigned Opcode, MVT::ValueType VT, SDOperand Chain, SDOperand Ptr, SDOperand SV, MVT::ValueType EVT); Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.75 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.76 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.75 Fri Nov 11 16:48:54 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Fri Nov 18 18:36:38 2005 @@ -107,12 +107,17 @@ // big. Like EXTRACT_ELEMENT, this can only be used before legalization. BUILD_PAIR, - // Simple integer binary arithmetic operators. ADD, SUB, MUL, SDIV, UDIV, SREM, UREM, // Simple binary floating point operators. FADD, FSUB, FMUL, FDIV, FREM, + + // Simple abstract vector operators. Unlike the integer and floating point + // binary operators, these nodes also take two additional operands: + // a constant element count, and a value type node indicating the type of + // the elements. The order is count, type, op0, op1. + VADD, VSUB, VMUL, // MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing // an unsigned/signed value of type i[2*n], then return the top part. @@ -209,6 +214,11 @@ // operand, then the same operands as an LLVM load/store instruction, then a // SRCVALUE node that provides alias analysis information. LOAD, STORE, + + // Abstract vector version of LOAD. VLOAD has a token chain as the first + // operand, followed by a pointer operand, a constant element count, a value + // type node indicating the type of the elements, and a SRCVALUE node. + VLOAD, // EXTLOAD, SEXTLOAD, ZEXTLOAD - These three operators all load a value from // memory and extend them to a larger value (e.g. load a byte into a word From lattner at cs.uiuc.edu Fri Nov 18 19:42:22 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 18 Nov 2005 19:42:22 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h Message-ID: <200511190142.TAA11844@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.69 -> 1.70 --- Log message: Add two new construction methods, patch by Evan Cheng --- Diffs of the changes: (+6 -0) SelectionDAG.h | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.69 llvm/include/llvm/CodeGen/SelectionDAG.h:1.70 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.69 Fri Nov 18 18:36:38 2005 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Fri Nov 18 19:42:10 2005 @@ -287,6 +287,12 @@ void SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT1, MVT::ValueType VT2, SDOperand Op1, SDOperand Op2, SDOperand Op3); + void SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT1, + MVT::ValueType VT2, SDOperand Op1, SDOperand Op2, + SDOperand Op3, SDOperand Op4); + void SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT1, + MVT::ValueType VT2, SDOperand Op1, SDOperand Op2, + SDOperand Op3, SDOperand Op4, SDOperand Op5); SDOperand getTargetNode(unsigned Opcode, MVT::ValueType VT) { return getNode(ISD::BUILTIN_OP_END+Opcode, VT); From lattner at cs.uiuc.edu Fri Nov 18 19:45:04 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 18 Nov 2005 19:45:04 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200511190145.TAA11982@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.213 -> 1.214 --- Log message: Add some method variants, patch by Evan Cheng --- Diffs of the changes: (+41 -15) SelectionDAG.cpp | 56 ++++++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 41 insertions(+), 15 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.213 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.214 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.213 Fri Nov 18 18:36:38 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Nov 18 19:44:53 2005 @@ -1399,6 +1399,7 @@ N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); N->setValueTypes(VT); } + void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT, SDOperand Op1) { RemoveNodeFromCSEMaps(N); @@ -1406,6 +1407,7 @@ N->setValueTypes(VT); N->setOperands(Op1); } + void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT, SDOperand Op1, SDOperand Op2) { @@ -1414,22 +1416,44 @@ N->setValueTypes(VT); N->setOperands(Op1, Op2); } -void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, - MVT::ValueType VT1, MVT::ValueType VT2, - SDOperand Op1, SDOperand Op2) { + +void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, + MVT::ValueType VT, SDOperand Op1, + SDOperand Op2, SDOperand Op3) { RemoveNodeFromCSEMaps(N); N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); - setNodeValueTypes(N, VT1, VT2); - N->setOperands(Op1, Op2); + N->setValueTypes(VT); + N->setOperands(Op1, Op2, Op3); } + void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT, SDOperand Op1, - SDOperand Op2, SDOperand Op3) { + SDOperand Op2, SDOperand Op3, SDOperand Op4) { RemoveNodeFromCSEMaps(N); N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); N->setValueTypes(VT); - N->setOperands(Op1, Op2, Op3); + N->setOperands(Op1, Op2, Op3, Op4); } + +void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, + MVT::ValueType VT, SDOperand Op1, + SDOperand Op2, SDOperand Op3, SDOperand Op4, + SDOperand Op5) { + RemoveNodeFromCSEMaps(N); + N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); + N->setValueTypes(VT); + N->setOperands(Op1, Op2, Op3, Op4, Op5); +} + +void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, + MVT::ValueType VT1, MVT::ValueType VT2, + SDOperand Op1, SDOperand Op2) { + RemoveNodeFromCSEMaps(N); + N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); + setNodeValueTypes(N, VT1, VT2); + N->setOperands(Op1, Op2); +} + void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT1, MVT::ValueType VT2, SDOperand Op1, SDOperand Op2, SDOperand Op3) { @@ -1440,24 +1464,26 @@ } void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, - MVT::ValueType VT, SDOperand Op1, - SDOperand Op2, SDOperand Op3, SDOperand Op4) { + MVT::ValueType VT1, MVT::ValueType VT2, + SDOperand Op1, SDOperand Op2, + SDOperand Op3, SDOperand Op4) { RemoveNodeFromCSEMaps(N); N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); - N->setValueTypes(VT); + setNodeValueTypes(N, VT1, VT2); N->setOperands(Op1, Op2, Op3, Op4); } + void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, - MVT::ValueType VT, SDOperand Op1, - SDOperand Op2, SDOperand Op3, SDOperand Op4, - SDOperand Op5) { + MVT::ValueType VT1, MVT::ValueType VT2, + SDOperand Op1, SDOperand Op2, + SDOperand Op3, SDOperand Op4, SDOperand Op5) { RemoveNodeFromCSEMaps(N); N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); - N->setValueTypes(VT); + setNodeValueTypes(N, VT1, VT2); N->setOperands(Op1, Op2, Op3, Op4, Op5); } -/// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead. +// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead. /// This can cause recursive merging of nodes in the DAG. /// /// This version assumes From/To have a single result value. From lattner at cs.uiuc.edu Fri Nov 18 20:11:19 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 18 Nov 2005 20:11:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200511190211.UAA12117@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.2 -> 1.3 --- Log message: Add load and other support to the dag-dag isel. Patch contributed by Evan Cheng! --- Diffs of the changes: (+225 -2) X86ISelDAGToDAG.cpp | 227 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 225 insertions(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.2 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.3 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.2 Wed Nov 16 16:59:19 2005 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Fri Nov 18 20:11:08 2005 @@ -15,6 +15,8 @@ #include "X86.h" #include "X86Subtarget.h" #include "X86ISelLowering.h" +#include "llvm/GlobalValue.h" +#include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/Target/TargetMachine.h" @@ -27,6 +29,32 @@ //===----------------------------------------------------------------------===// namespace { + /// X86ISelAddressMode - This corresponds to X86AddressMode, but uses + /// SDOperand's instead of register numbers for the leaves of the matched + /// tree. + struct X86ISelAddressMode { + enum { + RegBase, + FrameIndexBase, + } BaseType; + + struct { // This is really a union, discriminated by BaseType! + SDOperand Reg; + int FrameIndex; + } Base; + + unsigned Scale; + SDOperand IndexReg; + unsigned Disp; + GlobalValue *GV; + + X86ISelAddressMode() + : BaseType(RegBase), Scale(1), IndexReg(), Disp(), GV(0) { + } + }; +} + +namespace { Statistic<> NumFPKill("x86-codegen", "Number of FP_REG_KILL instructions added"); @@ -66,6 +94,15 @@ private: SDOperand Select(SDOperand N); + void SelectAddress(SDOperand N, X86ISelAddressMode &AM); + bool MatchAddress(SDOperand N, X86ISelAddressMode &AM); + + /// getI8Imm - Return a target constant with the specified value, of type + /// i8. + inline SDOperand getI8Imm(unsigned Imm) { + return CurDAG->getTargetConstant(Imm, MVT::i8); + } + /// getI16Imm - Return a target constant with the specified value, of type /// i16. inline SDOperand getI16Imm(unsigned Imm) { @@ -93,6 +130,141 @@ ScheduleAndEmitDAG(DAG); } +/// SelectAddress - Pattern match the maximal addressing mode for this node. +void X86DAGToDAGISel::SelectAddress(SDOperand N, X86ISelAddressMode &AM) { + MatchAddress(N, AM); + + if (AM.BaseType == X86ISelAddressMode::RegBase && !AM.Base.Reg.Val) { + AM.Base.Reg = CurDAG->getRegister(0, MVT::i32); + } else { + AM.Base.Reg = Select(AM.Base.Reg); + } + if (!AM.IndexReg.Val) { + AM.IndexReg = CurDAG->getRegister(0, MVT::i32); + } else { + AM.IndexReg = Select(AM.IndexReg); + } +} + +/// FIXME: copied from X86ISelPattern.cpp +/// MatchAddress - Add the specified node to the specified addressing mode, +/// returning true if it cannot be done. This just pattern matches for the +/// addressing mode +bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM) { + switch (N.getOpcode()) { + default: break; + case ISD::FrameIndex: + if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) { + AM.BaseType = X86ISelAddressMode::FrameIndexBase; + AM.Base.FrameIndex = cast(N)->getIndex(); + return false; + } + break; + case ISD::GlobalAddress: + if (AM.GV == 0) { + GlobalValue *GV = cast(N)->getGlobal(); + // For Darwin, external and weak symbols are indirect, so we want to load + // the value at address GV, not the value of GV itself. This means that + // the GlobalAddress must be in the base or index register of the address, + // not the GV offset field. + if (Subtarget->getIndirectExternAndWeakGlobals() && + (GV->hasWeakLinkage() || GV->isExternal())) { + break; + } else { + AM.GV = GV; + return false; + } + } + break; + case ISD::Constant: + AM.Disp += cast(N)->getValue(); + return false; + case ISD::SHL: + if (AM.IndexReg.Val == 0 && AM.Scale == 1) + if (ConstantSDNode *CN = dyn_cast(N.Val->getOperand(1))) { + unsigned Val = CN->getValue(); + if (Val == 1 || Val == 2 || Val == 3) { + AM.Scale = 1 << Val; + SDOperand ShVal = N.Val->getOperand(0); + + // Okay, we know that we have a scale by now. However, if the scaled + // value is an add of something and a constant, we can fold the + // constant into the disp field here. + if (ShVal.Val->getOpcode() == ISD::ADD && ShVal.hasOneUse() && + isa(ShVal.Val->getOperand(1))) { + AM.IndexReg = ShVal.Val->getOperand(0); + ConstantSDNode *AddVal = + cast(ShVal.Val->getOperand(1)); + AM.Disp += AddVal->getValue() << Val; + } else { + AM.IndexReg = ShVal; + } + return false; + } + } + break; + case ISD::MUL: + // X*[3,5,9] -> X+X*[2,4,8] + if (AM.IndexReg.Val == 0 && AM.BaseType == X86ISelAddressMode::RegBase && + AM.Base.Reg.Val == 0) + if (ConstantSDNode *CN = dyn_cast(N.Val->getOperand(1))) + if (CN->getValue() == 3 || CN->getValue() == 5 || CN->getValue() == 9) { + AM.Scale = unsigned(CN->getValue())-1; + + SDOperand MulVal = N.Val->getOperand(0); + SDOperand Reg; + + // Okay, we know that we have a scale by now. However, if the scaled + // value is an add of something and a constant, we can fold the + // constant into the disp field here. + if (MulVal.Val->getOpcode() == ISD::ADD && MulVal.hasOneUse() && + isa(MulVal.Val->getOperand(1))) { + Reg = MulVal.Val->getOperand(0); + ConstantSDNode *AddVal = + cast(MulVal.Val->getOperand(1)); + AM.Disp += AddVal->getValue() * CN->getValue(); + } else { + Reg = N.Val->getOperand(0); + } + + AM.IndexReg = AM.Base.Reg = Reg; + return false; + } + break; + + case ISD::ADD: { + X86ISelAddressMode Backup = AM; + if (!MatchAddress(N.Val->getOperand(0), AM) && + !MatchAddress(N.Val->getOperand(1), AM)) + return false; + AM = Backup; + if (!MatchAddress(N.Val->getOperand(1), AM) && + !MatchAddress(N.Val->getOperand(0), AM)) + return false; + AM = Backup; + break; + } + } + + // Is the base register already occupied? + if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base.Reg.Val) { + // If so, check to see if the scale index register is set. + if (AM.IndexReg.Val == 0) { + AM.IndexReg = N; + AM.Scale = 1; + return false; + } + + // Otherwise, we cannot select it. + return true; + } + + // Default, generate it as a register. + AM.BaseType = X86ISelAddressMode::RegBase; + AM.Base.Reg = N; + return false; +} + SDOperand X86DAGToDAGISel::Select(SDOperand Op) { SDNode *N = Op.Val; MVT::ValueType OpVT = Op.getValueType(); @@ -103,6 +275,21 @@ switch (N->getOpcode()) { default: break; + case ISD::SHL: + if (ConstantSDNode *CN = dyn_cast(N->getOperand(1))) { + if (CN->getValue() == 1) { // X = SHL Y, 1 -> X = ADD Y, Y + switch (OpVT) { + default: assert(0 && "Cannot shift this type!"); + case MVT::i8: Opc = X86::ADD8rr; break; + case MVT::i16: Opc = X86::ADD16rr; break; + case MVT::i32: Opc = X86::ADD32rr; break; + } + SDOperand Tmp0 = Select(N->getOperand(0)); + CurDAG->SelectNodeTo(N, Opc, MVT::i32, Tmp0, Tmp0); + return SDOperand(N, 0); + } + } + case ISD::RET: { SDOperand Chain = Select(N->getOperand(0)); // Token chain. switch (N->getNumOperands()) { @@ -131,11 +318,47 @@ if (X86Lowering.getBytesToPopOnReturn() == 0) CurDAG->SelectNodeTo(N, X86::RET, MVT::Other, Chain); else - CurDAG->SelectNodeTo(N, X86::RET, MVT::Other, Chain, - getI16Imm(X86Lowering.getBytesToPopOnReturn())); + CurDAG->SelectNodeTo(N, X86::RET, MVT::Other, + getI16Imm(X86Lowering.getBytesToPopOnReturn()), + Chain); return SDOperand(N, 0); } + + case ISD::LOAD: { + switch (N->getValueType(0)) { + default: assert(0 && "Cannot load this type!"); + case MVT::i1: + case MVT::i8: Opc = X86::MOV8rm; break; + case MVT::i16: Opc = X86::MOV16rm; break; + case MVT::i32: Opc = X86::MOV32rm; break; + case MVT::f32: Opc = X86::MOVSSrm; break; + case MVT::f64: Opc = X86::FLD64m; ContainsFPCode = true; break; + } + + if (ConstantPoolSDNode *CP = dyn_cast(N->getOperand(1))){ + unsigned CPIdx = BB->getParent()->getConstantPool()-> + getConstantPoolIndex(CP->get()); + // ??? + assert(0 && "Can't handle load from constant pool!"); + } else { + SDOperand Chain = Select(N->getOperand(0)); // Token chain. + X86ISelAddressMode AM; + SelectAddress(N->getOperand(1), AM); + SDOperand Scale = getI8Imm (AM.Scale); + SDOperand Disp = AM.GV ? CurDAG->getTargetGlobalAddress(AM.GV, MVT::i32) + : getI32Imm(AM.Disp); + if (AM.BaseType == X86ISelAddressMode::RegBase) { + CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other, + AM.Base.Reg, Scale, AM.IndexReg, Disp, Chain); + } else { + SDOperand Base = CurDAG->getFrameIndex(AM.Base.FrameIndex, MVT::i32); + CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other, + Base, Scale, AM.IndexReg, Disp, Chain); + } + } + return SDOperand(N, Op.ResNo); + } } return SelectCode(Op); From lattner at cs.uiuc.edu Fri Nov 18 23:51:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 18 Nov 2005 23:51:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200511190551.XAA12825@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.210 -> 1.211 --- Log message: Silence a bogus warning --- Diffs of the changes: (+2 -3) LegalizeDAG.cpp | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.210 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.211 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.210 Fri Nov 18 18:36:38 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Nov 18 23:51:46 2005 @@ -149,10 +149,9 @@ }; } -static unsigned scalarizedOpcode(unsigned VecOp, MVT::ValueType VT) { +static unsigned getScalarizedOpcode(unsigned VecOp, MVT::ValueType VT) { switch (VecOp) { default: assert(0 && "Don't know how to scalarize this opcode!"); - break; case ISD::VADD: return MVT::isInteger(VT) ? ISD::ADD : ISD::FADD; case ISD::VSUB: return MVT::isInteger(VT) ? ISD::SUB : ISD::FSUB; case ISD::VMUL: return MVT::isInteger(VT) ? ISD::MUL : ISD::FMUL; @@ -1696,7 +1695,7 @@ if (1 == cast(Tmp1)->getValue()) { MVT::ValueType SVT = cast(Tmp2)->getVT(); - Result = DAG.getNode(scalarizedOpcode(Node->getOpcode(), SVT), SVT, + Result = DAG.getNode(getScalarizedOpcode(Node->getOpcode(), SVT), SVT, LegalizeOp(Node->getOperand(2)), LegalizeOp(Node->getOperand(3))); } else { From lattner at cs.uiuc.edu Sat Nov 19 00:58:58 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 19 Nov 2005 00:58:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Message-ID: <200511190658.AAA13163@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGPrinter.cpp updated: 1.25 -> 1.26 --- Log message: Teach the graph viewer to handle register operands that are zero. --- Diffs of the changes: (+1 -1) SelectionDAGPrinter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp:1.25 llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp:1.26 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp:1.25 Fri Sep 30 19:15:11 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Sat Nov 19 00:58:46 2005 @@ -82,7 +82,7 @@ Op += LBB->getName(); //Op += " " + (const void*)BBDN->getBasicBlock(); } else if (const RegisterSDNode *R = dyn_cast(Node)) { - if (G && MRegisterInfo::isPhysicalRegister(R->getReg())) { + if (G && R->getReg() != 0 && MRegisterInfo::isPhysicalRegister(R->getReg())) { Op = Op + " " + G->getTarget().getRegisterInfo()->getName(R->getReg()); } else { Op += " #" + utostr(R->getReg()); From lattner at cs.uiuc.edu Sat Nov 19 01:00:21 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 19 Nov 2005 01:00:21 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Target.td Message-ID: <200511190700.BAA13265@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: Target.td updated: 1.57 -> 1.58 --- Log message: Capture more operand info, patch by Evan Cheng --- Diffs of the changes: (+2 -1) Target.td | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/Target.td diff -u llvm/lib/Target/Target.td:1.57 llvm/lib/Target/Target.td:1.58 --- llvm/lib/Target/Target.td:1.57 Thu Nov 17 18:53:32 2005 +++ llvm/lib/Target/Target.td Sat Nov 19 01:00:10 2005 @@ -172,9 +172,10 @@ /// by a target. Targets can optionally provide their own operand types as /// needed, though this should not be needed for RISC targets. class Operand { - int NumMIOperands = 1; ValueType Type = ty; string PrintMethod = "printOperand"; + int NumMIOperands = 1; + dag MIOperandInfo = (ops); } def i1imm : Operand; From lattner at cs.uiuc.edu Sat Nov 19 01:01:42 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 19 Nov 2005 01:01:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200511190701.BAA13329@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.138 -> 1.139 --- Log message: Teach the x86 backend about the register constraints of its addressing mode. Patch by Evan Cheng --- Diffs of the changes: (+2 -1) X86InstrInfo.td | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.138 llvm/lib/Target/X86/X86InstrInfo.td:1.139 --- llvm/lib/Target/X86/X86InstrInfo.td:1.138 Thu Nov 17 19:04:42 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Sat Nov 19 01:01:30 2005 @@ -17,8 +17,9 @@ // class X86MemOperand : Operand { - let NumMIOperands = 4; let PrintMethod = "printMemoryOperand"; + let NumMIOperands = 4; + let MIOperandInfo = (ops R32, i8imm, R32, i32imm); } def SSECC : Operand { let PrintMethod = "printSSECC"; From lattner at cs.uiuc.edu Sat Nov 19 01:06:08 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 19 Nov 2005 01:06:08 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeGenInstruction.h CodeGenTarget.cpp InstrInfoEmitter.cpp Message-ID: <200511190706.BAA13408@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeGenInstruction.h updated: 1.12 -> 1.13 CodeGenTarget.cpp updated: 1.41 -> 1.42 InstrInfoEmitter.cpp updated: 1.32 -> 1.33 --- Log message: Teach tblgen about instruction operands that have multiple MachineInstr operands, digging into them to find register values (used on X86). Patch by Evan Cheng! --- Diffs of the changes: (+29 -9) CodeGenInstruction.h | 11 +++++++++-- CodeGenTarget.cpp | 5 ++++- InstrInfoEmitter.cpp | 22 ++++++++++++++++------ 3 files changed, 29 insertions(+), 9 deletions(-) Index: llvm/utils/TableGen/CodeGenInstruction.h diff -u llvm/utils/TableGen/CodeGenInstruction.h:1.12 llvm/utils/TableGen/CodeGenInstruction.h:1.13 --- llvm/utils/TableGen/CodeGenInstruction.h:1.12 Fri Aug 26 15:42:52 2005 +++ llvm/utils/TableGen/CodeGenInstruction.h Sat Nov 19 01:05:57 2005 @@ -21,6 +21,7 @@ namespace llvm { class Record; + class DagInit; struct CodeGenInstruction { Record *TheDef; // The actual record defining this instruction. @@ -59,10 +60,16 @@ unsigned MIOperandNo; unsigned MINumOperands; // The number of operands. + /// MIOperandInfo - Default MI operand type. Note an operand may be made up + /// of multiple MI operands. + DagInit *MIOperandInfo; + OperandInfo(Record *R, MVT::ValueType T, const std::string &N, - const std::string &PMN, unsigned MION, unsigned MINO) + const std::string &PMN, unsigned MION, unsigned MINO, + DagInit *MIOI) + : Rec(R), Ty(T), Name(N), PrinterMethodName(PMN), MIOperandNo(MION), - MINumOperands(MINO) {} + MINumOperands(MINO), MIOperandInfo(MIOI) {} }; /// OperandList - The list of declared operands, along with their declared Index: llvm/utils/TableGen/CodeGenTarget.cpp diff -u llvm/utils/TableGen/CodeGenTarget.cpp:1.41 llvm/utils/TableGen/CodeGenTarget.cpp:1.42 --- llvm/utils/TableGen/CodeGenTarget.cpp:1.41 Fri Oct 28 17:49:02 2005 +++ llvm/utils/TableGen/CodeGenTarget.cpp Sat Nov 19 01:05:57 2005 @@ -267,12 +267,14 @@ MVT::ValueType Ty; std::string PrintMethod = "printOperand"; unsigned NumOps = 1; + DagInit *MIOpInfo; if (Rec->isSubClassOf("RegisterClass")) { Ty = getValueType(Rec->getValueAsDef("RegType")); } else if (Rec->isSubClassOf("Operand")) { Ty = getValueType(Rec->getValueAsDef("Type")); PrintMethod = Rec->getValueAsString("PrintMethod"); NumOps = Rec->getValueAsInt("NumMIOperands"); + MIOpInfo = Rec->getValueAsDag("MIOperandInfo"); } else if (Rec->getName() == "variable_ops") { hasVariableNumberOfOperands = true; continue; @@ -289,7 +291,8 @@ " has the same name as a previous operand!"; OperandList.push_back(OperandInfo(Rec, Ty, DI->getArgName(i), - PrintMethod, MIOperandNo, NumOps)); + PrintMethod, MIOperandNo, NumOps, + MIOpInfo)); MIOperandNo += NumOps; } } Index: llvm/utils/TableGen/InstrInfoEmitter.cpp diff -u llvm/utils/TableGen/InstrInfoEmitter.cpp:1.32 llvm/utils/TableGen/InstrInfoEmitter.cpp:1.33 --- llvm/utils/TableGen/InstrInfoEmitter.cpp:1.32 Tue Nov 1 14:07:00 2005 +++ llvm/utils/TableGen/InstrInfoEmitter.cpp Sat Nov 19 01:05:57 2005 @@ -62,13 +62,21 @@ return Result; // No info for variable operand instrs. for (unsigned i = 0, e = Inst.OperandList.size(); i != e; ++i) { - if (Inst.OperandList[i].Rec->isSubClassOf("RegisterClass")) + if (Inst.OperandList[i].Rec->isSubClassOf("RegisterClass")) { Result.push_back(Inst.OperandList[i].Rec); - else { + } else { // This might be a multiple operand thing. - // FIXME: Targets like X86 have registers in their multi-operand operands. - for (unsigned j = 0, e = Inst.OperandList[i].MINumOperands; j != e; ++j) - Result.push_back(0); + // Targets like X86 have registers in their multi-operand operands. + DagInit *MIOI = Inst.OperandList[i].MIOperandInfo; + unsigned NumDefs = MIOI->getNumArgs(); + for (unsigned j = 0, e = Inst.OperandList[i].MINumOperands; j != e; ++j) { + if (NumDefs <= j) { + Result.push_back(0); + } else { + DefInit *Def = dynamic_cast(MIOI->getArg(j)); + Result.push_back(Def ? Def->getDef() : 0); + } + } } } return Result; @@ -124,7 +132,9 @@ N = ++OperandListNum; OS << "static const TargetOperandInfo OperandInfo" << N << "[] = { "; for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) { - if (Record *RC = OperandInfo[i]) { + Record *RC = OperandInfo[i]; + // FIXME: We only care about register operands for now. + if (RC && RC->isSubClassOf("RegisterClass")) { OS << "{ &" << getQualifiedName(RC) << "RegClass }, "; } else { OS << "{ 0 }, "; From lattner at cs.uiuc.edu Sat Nov 19 01:44:21 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 19 Nov 2005 01:44:21 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Message-ID: <200511190744.BAA13562@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGPrinter.cpp updated: 1.26 -> 1.27 --- Log message: Improve Selection DAG printer portability. Patch by Owen Anderson! --- Diffs of the changes: (+6 -4) SelectionDAGPrinter.cpp | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp:1.26 llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp:1.27 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp:1.26 Sat Nov 19 00:58:46 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Sat Nov 19 01:44:09 2005 @@ -18,6 +18,7 @@ #include "llvm/Target/MRegisterInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/GraphWriter.h" +#include "llvm/System/Path.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Config/config.h" #include @@ -108,7 +109,8 @@ void SelectionDAG::viewGraph() { // This code is only for debugging! #ifndef NDEBUG - std::string Filename = "/tmp/dag." + + std::string TempDir = sys::Path::GetTemporaryDirectory().toString(); + std::string Filename = TempDir + "dag." + getMachineFunction().getFunction()->getName() + ".dot"; std::cerr << "Writing '" << Filename << "'... "; std::ofstream F(Filename.c_str()); @@ -135,13 +137,13 @@ #ifdef HAVE_GV std::cerr << "Running 'dot' program... " << std::flush; if (system(("dot -Tps -Nfontname=Courier -Gsize=7.5,10 " + Filename - + " > /tmp/dag.tempgraph.ps").c_str())) { + + " > " + TempDir +"dag.tempgraph.ps").c_str())) { std::cerr << "Error viewing graph: 'dot' not in path?\n"; } else { std::cerr << "\n"; - system(LLVM_PATH_GV " /tmp/dag.tempgraph.ps"); + system(LLVM_PATH_GV " " + TempDir + "dag.tempgraph.ps"); } - system(("rm " + Filename + " /tmp/dag.tempgraph.ps").c_str()); + system(("rm " + Filename + " "+ TempDir + "dag.tempgraph.ps").c_str()); return; #endif // HAVE_GV #endif // NDEBUG From lattner at cs.uiuc.edu Sat Nov 19 01:48:44 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 19 Nov 2005 01:48:44 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/CodeGenTarget.cpp Message-ID: <200511190748.BAA13610@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: CodeGenTarget.cpp updated: 1.42 -> 1.43 --- Log message: Initialize this variable on all paths, fixing a crasher in windows. Thanks to JeffC for pointing this out. --- Diffs of the changes: (+1 -1) CodeGenTarget.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/utils/TableGen/CodeGenTarget.cpp diff -u llvm/utils/TableGen/CodeGenTarget.cpp:1.42 llvm/utils/TableGen/CodeGenTarget.cpp:1.43 --- llvm/utils/TableGen/CodeGenTarget.cpp:1.42 Sat Nov 19 01:05:57 2005 +++ llvm/utils/TableGen/CodeGenTarget.cpp Sat Nov 19 01:48:33 2005 @@ -267,7 +267,7 @@ MVT::ValueType Ty; std::string PrintMethod = "printOperand"; unsigned NumOps = 1; - DagInit *MIOpInfo; + DagInit *MIOpInfo = 0; if (Rec->isSubClassOf("RegisterClass")) { Ty = getValueType(Rec->getValueAsDef("RegType")); } else if (Rec->isSubClassOf("Operand")) { From lattner at cs.uiuc.edu Sat Nov 19 12:40:54 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 19 Nov 2005 12:40:54 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200511191840.MAA00489@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.102 -> 1.103 --- Log message: Unbreak codegen of bools. This should fix the llc/jit/llc-beta failures from last night. --- Diffs of the changes: (+1 -1) SelectionDAGISel.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.102 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.103 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.102 Fri Nov 18 18:36:38 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Sat Nov 19 12:40:42 2005 @@ -511,7 +511,7 @@ SDOperand Op1 = getValue(I.getOperand(0)); SDOperand Op2 = getValue(I.getOperand(1)); - if (Ty->isInteger()) { + if (Ty->isIntegral()) { setValue(&I, DAG.getNode(IntOp, Op1.getValueType(), Op1, Op2)); } else if (Ty->isFloatingPoint()) { setValue(&I, DAG.getNode(FPOp, Op1.getValueType(), Op1, Op2)); From lattner at cs.uiuc.edu Sat Nov 19 21:46:03 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 19 Nov 2005 21:46:03 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Message-ID: <200511200346.VAA13878@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGPrinter.cpp updated: 1.27 -> 1.28 --- Log message: more progress towards bug 291: http://llvm.cs.uiuc.edu/PR291 being finished. Patch by Owen Anderson, HAVE_GV case fixed up by me. --- Diffs of the changes: (+17 -12) SelectionDAGPrinter.cpp | 29 +++++++++++++++++------------ 1 files changed, 17 insertions(+), 12 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp:1.27 llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp:1.28 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp:1.27 Sat Nov 19 01:44:09 2005 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp Sat Nov 19 21:45:52 2005 @@ -109,11 +109,11 @@ void SelectionDAG::viewGraph() { // This code is only for debugging! #ifndef NDEBUG - std::string TempDir = sys::Path::GetTemporaryDirectory().toString(); - std::string Filename = TempDir + "dag." + - getMachineFunction().getFunction()->getName() + ".dot"; - std::cerr << "Writing '" << Filename << "'... "; - std::ofstream F(Filename.c_str()); + sys::Path TempDir = sys::Path::GetTemporaryDirectory(); + sys::Path Filename = TempDir; + Filename.appendComponent("dag." + getMachineFunction().getFunction()->getName() + ".dot"); + std::cerr << "Writing '" << Filename.toString() << "'... "; + std::ofstream F(Filename.toString().c_str()); if (!F) { std::cerr << " error opening file for writing!\n"; @@ -126,24 +126,28 @@ #ifdef HAVE_GRAPHVIZ std::cerr << "Running 'Graphviz' program... " << std::flush; - if (system((LLVM_PATH_GRAPHVIZ " " + Filename).c_str())) { + if (system((LLVM_PATH_GRAPHVIZ " " + Filename.toString()).c_str())) { std::cerr << "Error viewing graph: 'Graphviz' not in path?\n"; } else { - system(("rm " + Filename).c_str()); + Filename.eraseFromDisk(); return; } #endif // HAVE_GRAPHVIZ #ifdef HAVE_GV std::cerr << "Running 'dot' program... " << std::flush; - if (system(("dot -Tps -Nfontname=Courier -Gsize=7.5,10 " + Filename - + " > " + TempDir +"dag.tempgraph.ps").c_str())) { + sys::Path PSFilename = TempDir; + PSFilename.appendComponent("dag.tempgraph.ps"); + if (system(("dot -Tps -Nfontname=Courier -Gsize=7.5,10 " + Filename.toString() + + " > " + PSFilename.toString()).c_str())) { std::cerr << "Error viewing graph: 'dot' not in path?\n"; } else { std::cerr << "\n"; - system(LLVM_PATH_GV " " + TempDir + "dag.tempgraph.ps"); + system((LLVM_PATH_GV " " + PSFilename.toString()).c_str()); + system((LLVM_PATH_GV " "+TempDir.toString()+ "dag.tempgraph.ps").c_str()); } - system(("rm " + Filename + " "+ TempDir + "dag.tempgraph.ps").c_str()); + Filename.eraseFromDisk(); + PSFilename.eraseFromDisk(); return; #endif // HAVE_GV #endif // NDEBUG @@ -151,6 +155,7 @@ << "systems with Graphviz or gv!\n"; #ifndef NDEBUG - system(("rm " + Filename).c_str()); + Filename.eraseFromDisk(); + TempDir.eraseFromDisk(true); #endif } From alenhar2 at cs.uiuc.edu Sun Nov 20 15:32:20 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Sun, 20 Nov 2005 15:32:20 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200511202132.PAA31355@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.211 -> 1.212 --- Log message: The first patch of X86 support for read cycle counter --- Diffs of the changes: (+12 -0) LegalizeDAG.cpp | 12 ++++++++++++ 1 files changed, 12 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.211 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.212 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.211 Fri Nov 18 23:51:46 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sun Nov 20 15:32:07 2005 @@ -1168,6 +1168,7 @@ if (Tmp1 != Node->getOperand(0)) Result = DAG.getNode(ISD::READCYCLECOUNTER, MVT::i64, Tmp1); break; + case ISD::TRUNCSTORE: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. Tmp3 = LegalizeOp(Node->getOperand(2)); // Legalize the pointer. @@ -3336,6 +3337,17 @@ Hi = DAG.getConstant(0, NVT); break; } + + case ISD::READCYCLECOUNTER: + if (TLI.getOperationAction(ISD::READCYCLECOUNTER, VT) == TargetLowering::Custom) { + SDOperand Chain = LegalizeOp(Node->getOperand(0)); + AddLegalizedOperand(SDOperand(Node, 1), Chain); + SDOperand t = TLI.LowerOperation(Op, DAG); + ExpandOp(t, Lo, Hi); + } else + assert(0 && "Must custom expand ReadCycleCounter"); + break; + // These operators cannot be expanded directly, emit them as calls to // library functions. case ISD::FP_TO_SINT: From alenhar2 at cs.uiuc.edu Sun Nov 20 15:41:22 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Sun, 20 Nov 2005 15:41:22 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86ISelPattern.cpp X86InstrInfo.td Message-ID: <200511202141.PAA31486@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.1 -> 1.2 X86ISelLowering.h updated: 1.1 -> 1.2 X86ISelPattern.cpp updated: 1.185 -> 1.186 X86InstrInfo.td updated: 1.139 -> 1.140 --- Log message: The second patch of X86 support for read cycle counter. --- Diffs of the changes: (+20 -0) X86ISelLowering.cpp | 7 +++++++ X86ISelLowering.h | 4 ++++ X86ISelPattern.cpp | 5 +++++ X86InstrInfo.td | 4 ++++ 4 files changed, 20 insertions(+) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.1 llvm/lib/Target/X86/X86ISelLowering.cpp:1.2 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.1 Mon Nov 14 18:40:24 2005 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Sun Nov 20 15:41:10 2005 @@ -101,6 +101,7 @@ setOperationAction(ISD::CTPOP , MVT::i32 , Expand); setOperationAction(ISD::CTTZ , MVT::i32 , Expand); setOperationAction(ISD::CTLZ , MVT::i32 , Expand); + setOperationAction(ISD::READCYCLECOUNTER , MVT::i64 , Custom); setOperationAction(ISD::READIO , MVT::i1 , Expand); setOperationAction(ISD::READIO , MVT::i8 , Expand); @@ -912,5 +913,11 @@ return DAG.getLoad(Op.getValueType(), FIST, StackSlot, DAG.getSrcValue(NULL)); } + case ISD::READCYCLECOUNTER: { + SDOperand rd = DAG.getNode(X86ISD::RDTSC_DAG, MVT::Other, Op.getOperand(0)); + SDOperand Lo = DAG.getCopyFromReg(rd, X86::EAX, MVT::i32); + SDOperand Hi = DAG.getCopyFromReg(rd, X86::EDX, MVT::i32); + return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); + } } } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.1 llvm/lib/Target/X86/X86ISelLowering.h:1.2 --- llvm/lib/Target/X86/X86ISelLowering.h:1.1 Mon Nov 14 18:40:24 2005 +++ llvm/lib/Target/X86/X86ISelLowering.h Sun Nov 20 15:41:10 2005 @@ -62,6 +62,10 @@ /// LLVM. CALL, TAILCALL, + + /// RDTSC_DAG - This operation implements the lowering for + /// readcyclecounter + RDTSC_DAG, }; } Index: llvm/lib/Target/X86/X86ISelPattern.cpp diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.185 llvm/lib/Target/X86/X86ISelPattern.cpp:1.186 --- llvm/lib/Target/X86/X86ISelPattern.cpp:1.185 Mon Nov 14 18:40:24 2005 +++ llvm/lib/Target/X86/X86ISelPattern.cpp Sun Nov 20 15:41:10 2005 @@ -3090,6 +3090,11 @@ default: Node->dump(); std::cerr << "\n"; assert(0 && "Node not handled yet!"); + case X86ISD::RDTSC_DAG: + Select(Node->getOperand(0)); //Chain + BuildMI(BB, X86::RDTSC, 0); + return; + case ISD::EntryToken: return; // Noop case ISD::TokenFactor: if (Node->getNumOperands() == 2) { Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.139 llvm/lib/Target/X86/X86InstrInfo.td:1.140 --- llvm/lib/Target/X86/X86InstrInfo.td:1.139 Sat Nov 19 01:01:30 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Sun Nov 20 15:41:10 2005 @@ -167,6 +167,10 @@ def PHI : I<0, Pseudo, (ops variable_ops), "PHINODE">; // PHI node. def NOOP : I<0x90, RawFrm, (ops), "nop">; // nop +//FIXME: encode this correctly +let Defs = [EAX, EDX] in + def RDTSC : I<0, Pseudo, (ops ), "rdtsc">; //in binary, this inst is 0x0f 0x31 + def ADJCALLSTACKDOWN : I<0, Pseudo, (ops i32imm:$amt), "#ADJCALLSTACKDOWN">; def ADJCALLSTACKUP : I<0, Pseudo, (ops i32imm:$amt1, i32imm:$amt2), "#ADJCALLSTACKUP">; From alenhar2 at cs.uiuc.edu Sun Nov 20 15:42:11 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Sun, 20 Nov 2005 15:42:11 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/rdtsc.ll Message-ID: <200511202142.PAA31513@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: rdtsc.ll added (r1.1) --- Log message: check that rdtsc is generated from readcyclecounter --- Diffs of the changes: (+10 -0) rdtsc.ll | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/test/Regression/CodeGen/X86/rdtsc.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/rdtsc.ll:1.1 *** /dev/null Sun Nov 20 15:42:09 2005 --- llvm/test/Regression/CodeGen/X86/rdtsc.ll Sun Nov 20 15:41:59 2005 *************** *** 0 **** --- 1,10 ---- + ; RUN: llvm-as < %s | llc -march=x86 | grep rptsc + + declare ulong %llvm.readcyclecounter() + + void %foo() { + entry: + %tmp.1 = call ulong %llvm.readcyclecounter () + ret void + } + From alenhar2 at cs.uiuc.edu Sun Nov 20 15:43:01 2005 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Sun, 20 Nov 2005 15:43:01 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/rdtsc.ll Message-ID: <200511202143.PAA31555@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: rdtsc.ll updated: 1.1 -> 1.2 --- Log message: oops --- Diffs of the changes: (+1 -1) rdtsc.ll | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/test/Regression/CodeGen/X86/rdtsc.ll diff -u llvm/test/Regression/CodeGen/X86/rdtsc.ll:1.1 llvm/test/Regression/CodeGen/X86/rdtsc.ll:1.2 --- llvm/test/Regression/CodeGen/X86/rdtsc.ll:1.1 Sun Nov 20 15:41:59 2005 +++ llvm/test/Regression/CodeGen/X86/rdtsc.ll Sun Nov 20 15:42:49 2005 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -march=x86 | grep rptsc +; RUN: llvm-as < %s | llc -march=x86 | grep rdtsc declare ulong %llvm.readcyclecounter() From lattner at cs.uiuc.edu Sun Nov 20 15:47:04 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 20 Nov 2005 15:47:04 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/rdtsc.ll Message-ID: <200511202147.PAA31627@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: rdtsc.ll updated: 1.2 -> 1.3 --- Log message: This should not be dce'd --- Diffs of the changes: (+2 -3) rdtsc.ll | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) Index: llvm/test/Regression/CodeGen/X86/rdtsc.ll diff -u llvm/test/Regression/CodeGen/X86/rdtsc.ll:1.2 llvm/test/Regression/CodeGen/X86/rdtsc.ll:1.3 --- llvm/test/Regression/CodeGen/X86/rdtsc.ll:1.2 Sun Nov 20 15:42:49 2005 +++ llvm/test/Regression/CodeGen/X86/rdtsc.ll Sun Nov 20 15:46:52 2005 @@ -2,9 +2,8 @@ declare ulong %llvm.readcyclecounter() -void %foo() { -entry: +ulong %foo() { %tmp.1 = call ulong %llvm.readcyclecounter () -ret void +ret ulong %tmp.1 } From lattner at cs.uiuc.edu Sun Nov 20 16:01:52 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 20 Nov 2005 16:01:52 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200511202201.QAA31898@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.2 -> 1.3 --- Log message: use chain operands to ensure the copies don't wander from the rdtsc instruction. --- Diffs of the changes: (+9 -3) X86ISelLowering.cpp | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.2 llvm/lib/Target/X86/X86ISelLowering.cpp:1.3 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.2 Sun Nov 20 15:41:10 2005 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Sun Nov 20 16:01:40 2005 @@ -914,9 +914,15 @@ DAG.getSrcValue(NULL)); } case ISD::READCYCLECOUNTER: { - SDOperand rd = DAG.getNode(X86ISD::RDTSC_DAG, MVT::Other, Op.getOperand(0)); - SDOperand Lo = DAG.getCopyFromReg(rd, X86::EAX, MVT::i32); - SDOperand Hi = DAG.getCopyFromReg(rd, X86::EDX, MVT::i32); + std::vector Tys; + Tys.push_back(MVT::Other); + Tys.push_back(MVT::Flag); + std::vector Ops; + Ops.push_back(Op.getOperand(0)); + SDOperand rd = DAG.getNode(X86ISD::RDTSC_DAG, Tys, Ops); + SDOperand Lo = DAG.getCopyFromReg(rd, X86::EAX, MVT::i32, rd.getValue(1)); + SDOperand Hi = DAG.getCopyFromReg(Lo.getValue(1), X86::EDX, + MVT::i32, Lo.getValue(2)); return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); } } From lattner at cs.uiuc.edu Sun Nov 20 16:13:30 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 20 Nov 2005 16:13:30 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200511202213.QAA32042@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.140 -> 1.141 --- Log message: encode rdtsc correctly --- Diffs of the changes: (+7 -4) X86InstrInfo.td | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.140 llvm/lib/Target/X86/X86InstrInfo.td:1.141 --- llvm/lib/Target/X86/X86InstrInfo.td:1.140 Sun Nov 20 15:41:10 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Sun Nov 20 16:13:18 2005 @@ -167,10 +167,6 @@ def PHI : I<0, Pseudo, (ops variable_ops), "PHINODE">; // PHI node. def NOOP : I<0x90, RawFrm, (ops), "nop">; // nop -//FIXME: encode this correctly -let Defs = [EAX, EDX] in - def RDTSC : I<0, Pseudo, (ops ), "rdtsc">; //in binary, this inst is 0x0f 0x31 - def ADJCALLSTACKDOWN : I<0, Pseudo, (ops i32imm:$amt), "#ADJCALLSTACKDOWN">; def ADJCALLSTACKUP : I<0, Pseudo, (ops i32imm:$amt1, i32imm:$amt2), "#ADJCALLSTACKUP">; @@ -1610,6 +1606,13 @@ } //===----------------------------------------------------------------------===// +// Miscellaneous Instructions +//===----------------------------------------------------------------------===// + +def RDTSC : I<0x31, RawFrm, (ops), "rdtsc">, TB, Imp<[],[EAX,EDX]>; + + +//===----------------------------------------------------------------------===// // Stack-based Floating point support //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Sun Nov 20 16:56:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 20 Nov 2005 16:56:09 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200511202256.QAA32611@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.76 -> 1.77 --- Log message: add a new node type --- Diffs of the changes: (+7 -0) SelectionDAGNodes.h | 7 +++++++ 1 files changed, 7 insertions(+) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.76 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.77 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.76 Fri Nov 18 18:36:38 2005 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Sun Nov 20 16:55:57 2005 @@ -106,6 +106,13 @@ // two values of the same integer value type, this produces a value twice as // big. Like EXTRACT_ELEMENT, this can only be used before legalization. BUILD_PAIR, + + // MERGE_VALUES - This node takes multiple discrete operands and returns + // them all as its individual results. This nodes has exactly the same + // number of inputs and outputs, and is only valid before legalization. + // This node is useful for some pieces of the code generator that want to + // think about a single node with multiple results, not multiple nodes. + MERGE_VALUES, // Simple integer binary arithmetic operators. ADD, SUB, MUL, SDIV, UDIV, SREM, UREM, From lattner at cs.uiuc.edu Sun Nov 20 16:57:09 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 20 Nov 2005 16:57:09 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200511202257.QAA32697@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.212 -> 1.213 --- Log message: Legalize MERGE_VALUES, expand READCYCLECOUNTER correctly, so it doesn't break control dependence. --- Diffs of the changes: (+13 -8) LegalizeDAG.cpp | 21 +++++++++++++-------- 1 files changed, 13 insertions(+), 8 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.212 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.213 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.212 Sun Nov 20 15:32:07 2005 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sun Nov 20 16:56:56 2005 @@ -561,6 +561,8 @@ Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1, Node->getOperand(1)); break; + case ISD::MERGE_VALUES: + return LegalizeOp(Node->getOperand(Op.ResNo)); case ISD::CopyFromReg: Tmp1 = LegalizeOp(Node->getOperand(0)); if (Tmp1 != Node->getOperand(0)) @@ -3338,15 +3340,18 @@ break; } - case ISD::READCYCLECOUNTER: - if (TLI.getOperationAction(ISD::READCYCLECOUNTER, VT) == TargetLowering::Custom) { - SDOperand Chain = LegalizeOp(Node->getOperand(0)); - AddLegalizedOperand(SDOperand(Node, 1), Chain); - SDOperand t = TLI.LowerOperation(Op, DAG); - ExpandOp(t, Lo, Hi); - } else - assert(0 && "Must custom expand ReadCycleCounter"); + case ISD::READCYCLECOUNTER: { + assert(TLI.getOperationAction(ISD::READCYCLECOUNTER, VT) == + TargetLowering::Custom && + "Must custom expand ReadCycleCounter"); + SDOperand T = TLI.LowerOperation(Op, DAG); + assert(T.Val && "Node must be custom expanded!"); + Lo = LegalizeOp(T.getValue(0)); + Hi = LegalizeOp(T.getValue(1)); + AddLegalizedOperand(SDOperand(Node, 1), // Remember we legalized the chain. + LegalizeOp(T.getValue(2))); break; + } // These operators cannot be expanded directly, emit them as calls to // library functions. From lattner at cs.uiuc.edu Sun Nov 20 16:57:32 2005 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 20 Nov 2005 16:57:32 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200511202257.QAA32728@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.3 -> 1.4 --- Log message: Lower READCYCLECOUNTER correctly, preserving the chain result --- Diffs of the changes: (+8 -4) X86ISelLowering.cpp | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.3 llvm/lib/Target/X86/X86ISelLowering.cpp:1.4 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.3 Sun Nov 20 16:01:40 2005 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Sun Nov 20 16:57:19 2005 @@ -920,10 +920,14 @@ std::vector Ops; Ops.push_back(Op.getOperand(0)); SDOperand rd = DAG.getNode(X86ISD::RDTSC_DAG, Tys, Ops); - SDOperand Lo = DAG.getCopyFromReg(rd, X86::EAX, MVT::i32, rd.getValue(1)); - SDOperand Hi = DAG.getCopyFromReg(Lo.getValue(1), X86::EDX, - MVT::i32, Lo.getValue(2)); - return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); + Ops.clear(); + Ops.push_back(DAG.getCopyFromReg(rd, X86::EAX, MVT::i32, rd.getValue(1))); + Ops.push_back(DAG.getCopyFromReg(Ops[0].getValue(1), X86::EDX, + MVT::i32, Ops[0].getValue(2))); + Ops.push_back(Ops[1].getValue(1)); + Tys[0] = Tys[1] = MVT::i32; + Tys.push_back(MVT::Other); + return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops); } } }