From criswell at cs.uiuc.edu Mon Jun 7 09:27:01 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Jun 7 09:27:01 2004 Subject: [llvm-commits] CVS: llvm/autoconf/configure.ac Message-ID: <200406071426.JAA29759@choi.cs.uiuc.edu> Changes in directory llvm/autoconf: configure.ac updated: 1.89 -> 1.90 --- Log message: Added checks for mkstemp and getrusage. --- Diffs of the changes: (+1 -1) Index: llvm/autoconf/configure.ac diff -u llvm/autoconf/configure.ac:1.89 llvm/autoconf/configure.ac:1.90 --- llvm/autoconf/configure.ac:1.89 Wed Jun 2 18:32:17 2004 +++ llvm/autoconf/configure.ac Mon Jun 7 09:26:23 2004 @@ -285,7 +285,7 @@ fi AC_HEADER_MMAP_ANONYMOUS AC_TYPE_SIGNAL -AC_CHECK_FUNCS(getcwd gettimeofday strdup strtoq strtoll backtrace isatty) +AC_CHECK_FUNCS(getcwd gettimeofday strdup strtoq strtoll backtrace isatty mkstemp getrusage) AC_CHECK_FUNC(mprotect,,AC_MSG_ERROR([Function mprotect() required but not found])) dnl Determine if the linker supports the -R option. From criswell at cs.uiuc.edu Mon Jun 7 09:27:03 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Jun 7 09:27:03 2004 Subject: [llvm-commits] CVS: llvm/include/Config/config.h.in Message-ID: <200406071426.JAA29766@choi.cs.uiuc.edu> Changes in directory llvm/include/Config: config.h.in updated: 1.17 -> 1.18 --- Log message: Added checks for mkstemp and getrusage. --- Diffs of the changes: (+6 -0) Index: llvm/include/Config/config.h.in diff -u llvm/include/Config/config.h.in:1.17 llvm/include/Config/config.h.in:1.18 --- llvm/include/Config/config.h.in:1.17 Thu May 27 15:40:39 2004 +++ llvm/include/Config/config.h.in Mon Jun 7 09:26:24 2004 @@ -107,6 +107,12 @@ /* Define to 1 if you have the `strtoq' function. */ #undef HAVE_STRTOQ +/* Define to 1 if you have the mkstemp function */ +#undef HAVE_MKSTEMP + +/* Define to 1 if you have the getrusage function */ +#undef HAVE_GETRUSAGE + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MMAN_H From criswell at cs.uiuc.edu Mon Jun 7 09:27:05 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Jun 7 09:27:05 2004 Subject: [llvm-commits] CVS: llvm/configure Message-ID: <200406071426.JAA29771@choi.cs.uiuc.edu> Changes in directory llvm: configure updated: 1.91 -> 1.92 --- Log message: Added checks for mkstemp and getrusage. --- Diffs of the changes: (+35 -33) Index: llvm/configure diff -u llvm/configure:1.91 llvm/configure:1.92 --- llvm/configure:1.91 Wed Jun 2 18:31:01 2004 +++ llvm/configure Mon Jun 7 09:26:11 2004 @@ -1864,15 +1864,15 @@ fi ;; + *-*-cygwin*) + OS=Cygwin + + ;; *-*-darwin*) OS=Darwin ;; - *-*-cygwin*) - OS=Cygwin - - ;; *) OS=Unknown @@ -4048,7 +4048,7 @@ ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 4047 "configure"' > conftest.$ac_ext + echo '#line 4051 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -4889,7 +4889,7 @@ # Provide some information about the compiler. -echo "$as_me:4888:" \ +echo "$as_me:4892:" \ "checking for Fortran 77 compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 @@ -5894,11 +5894,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:5893: $lt_compile\"" >&5) + (eval echo "\"\$as_me:5897: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:5897: \$? = $ac_status" >&5 + echo "$as_me:5901: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -6126,11 +6126,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6125: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6129: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6129: \$? = $ac_status" >&5 + echo "$as_me:6133: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -6193,11 +6193,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6192: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6196: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:6196: \$? = $ac_status" >&5 + echo "$as_me:6200: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -8205,7 +8205,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:10438: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:10438: \$? = $ac_status" >&5 + echo "$as_me:10442: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -10502,11 +10502,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:10501: $lt_compile\"" >&5) + (eval echo "\"\$as_me:10505: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:10505: \$? = $ac_status" >&5 + echo "$as_me:10509: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -11745,7 +11745,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:12668: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:12668: \$? = $ac_status" >&5 + echo "$as_me:12672: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -12732,11 +12732,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12731: $lt_compile\"" >&5) + (eval echo "\"\$as_me:12735: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:12735: \$? = $ac_status" >&5 + echo "$as_me:12739: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14672,11 +14672,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14671: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14675: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14675: \$? = $ac_status" >&5 + echo "$as_me:14679: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -14904,11 +14904,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14903: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14907: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14907: \$? = $ac_status" >&5 + echo "$as_me:14911: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -14971,11 +14971,11 @@ -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14970: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14974: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14974: \$? = $ac_status" >&5 + echo "$as_me:14978: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -16983,7 +16983,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5 From llvm at cs.uiuc.edu Mon Jun 7 12:51:29 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Mon Jun 7 12:51:29 2004 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Analyzer/ Message-ID: <200406071744.MAA21375@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Analyzer: --- Log message: Directory /var/cvs/llvm/llvm/lib/Bytecode/Analyzer added to the repository --- Diffs of the changes: (+0 -0) From llvm at cs.uiuc.edu Mon Jun 7 12:59:01 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Mon Jun 7 12:59:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Makefile Message-ID: <200406071753.MAA21469@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode: Makefile updated: 1.2 -> 1.3 --- Log message: Commit For New Tool: llvm-abcd (Analysis of ByteCode Dumper). This tool will (eventually) provide statistical analysis of bytecode files as well as the ability to dump them in a low level format (slot numbers not resolved). The purpose of this is to aid in the Type!=Value change of bug 122: http://llvm.cs.uiuc.edu/PR122 . With this initial release, llvm-abcd merely dumps out the bytecode. However, the infrastructure for separating bytecode parsing from handling the parsing events is in place. The style chosen is similar to SAX XML parsing where a handler object is called to handlign the parsing events. This probably isn't useful to anyone but me right now as there is no analysis yet, and the dumper doesn't work on every bytecode file. It will probably be useful by the end of this week. Note that there is some duplication of code from the bytecode reader. This was done to eliminate errors from being introduced in the reader and to minimize the impact to other LLVM developers. At some point, the Analyzer and the Reader will be integrated to use the same infrastructure. Also, sorry for the minor change to Instruction.h but I just couldn't bring myself to write code that depends on Instruction internals. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Bytecode/Makefile diff -u llvm/lib/Bytecode/Makefile:1.2 llvm/lib/Bytecode/Makefile:1.3 --- llvm/lib/Bytecode/Makefile:1.2 Mon Oct 20 17:26:56 2003 +++ llvm/lib/Bytecode/Makefile Mon Jun 7 12:53:43 2004 @@ -7,7 +7,7 @@ # ##===----------------------------------------------------------------------===## LEVEL = ../.. -DIRS = Reader Writer +DIRS = Analyzer Reader Writer include $(LEVEL)/Makefile.common From llvm at cs.uiuc.edu Mon Jun 7 12:59:08 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Mon Jun 7 12:59:08 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Bytecode/Analyzer.h Message-ID: <200406071753.MAA21472@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Bytecode: Analyzer.h added (r1.1) --- Log message: Commit For New Tool: llvm-abcd (Analysis of ByteCode Dumper). This tool will (eventually) provide statistical analysis of bytecode files as well as the ability to dump them in a low level format (slot numbers not resolved). The purpose of this is to aid in the Type!=Value change of bug 122: http://llvm.cs.uiuc.edu/PR122 . With this initial release, llvm-abcd merely dumps out the bytecode. However, the infrastructure for separating bytecode parsing from handling the parsing events is in place. The style chosen is similar to SAX XML parsing where a handler object is called to handlign the parsing events. This probably isn't useful to anyone but me right now as there is no analysis yet, and the dumper doesn't work on every bytecode file. It will probably be useful by the end of this week. Note that there is some duplication of code from the bytecode reader. This was done to eliminate errors from being introduced in the reader and to minimize the impact to other LLVM developers. At some point, the Analyzer and the Reader will be integrated to use the same infrastructure. Also, sorry for the minor change to Instruction.h but I just couldn't bring myself to write code that depends on Instruction internals. --- Diffs of the changes: (+97 -0) Index: llvm/include/llvm/Bytecode/Analyzer.h diff -c /dev/null llvm/include/llvm/Bytecode/Analyzer.h:1.1 *** /dev/null Mon Jun 7 12:53:53 2004 --- llvm/include/llvm/Bytecode/Analyzer.h Mon Jun 7 12:53:43 2004 *************** *** 0 **** --- 1,97 ---- + //===-- llvm/Bytecode/Analyzer.h - Analyzer for bytecode files --*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Reid Spencer and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This functionality is implemented by the lib/Bytecode/Analysis library. + // This library is used to read VM bytecode files from an iostream and print + // out a diagnostic analysis of the contents of the file. It is intended for + // three uses: (a) understanding the bytecode format, (b) ensuring correctness + // of bytecode format, (c) statistical analysis of generated bytecode files. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_BYTECODE_ANALYZER_H + #define LLVM_BYTECODE_ANALYZER_H + + #include + #include + + namespace llvm { + + /// This structure is used to contain the output of the Bytecode Analysis + /// library. It simply contains fields to hold each item of the analysis + /// results. + /// @brief Bytecode Analysis results structure + struct BytecodeAnalysis { + unsigned byteSize; ///< The size of the bytecode file in bytes + unsigned numTypes; ///< The number of types + unsigned numValues; ///< The number of values + unsigned numFunctions; ///< The number of functions defined + unsigned numConstants; ///< The number of constants + unsigned numGlobalVars; ///< The number of global variables + unsigned numInstructions; ///< The number of instructions in all functions + unsigned numBasicBlocks; ///< The number of BBs in all functions + unsigned numOperands; ///< The number of BBs in all functions + unsigned maxTypeSlot; ///< The maximum slot number for types + unsigned maxValueSlot; ///< The maximum slot number for values + double density; ///< Density of file (bytes/defs) + + /// A structure that contains various pieces of information related to + /// an analysis of a single function. + struct BytecodeFunctionInfo { + unsigned byteSize; ///< The size of the function in bytecode bytes + unsigned numInstructions; ///< The number of instructions in the function + unsigned numBasicBlocks; ///< The number of basic blocks in the function + unsigned numOperands; ///< The number of operands in the function + double density; ///< Density of function + double vbrEffectiveness; ///< Effectiveness of variable bit rate encoding. + ///< This is the average number of bytes per unsigned value written in the + ///< vbr encoding. A "perfect" score of 1.0 means all vbr values were + ///< encoded in one byte. A score between 1.0 and 4.0 means that some + ///< savings were achieved. A score of 4.0 means vbr didn't help. A score + ///< greater than 4.0 means vbr negatively impacted size of the file. + }; + + /// A mapping of function names to the collected information about the + /// function. + std::map FunctionInfo; + + /// Flags for what should be done + bool dumpBytecode; + }; + + /// This function is the main entry point into the bytecode analysis library. It + /// allows you to simply provide a \P filename and storage for the \P Results + /// that will be filled in with the analysis results. + /// @brief Analyze contents of a bytecode File + void AnalyzeBytecodeFile( + const std::string& Filename, ///< The name of the bytecode file to read + BytecodeAnalysis& Results, ///< The results of the analysis + std::string* ErrorStr = 0 ///< Errors, if any. + ); + + /// This function is an alternate entry point into the bytecode analysis + /// library. It allows you to provide an arbitrary memory buffer which is + /// assumed to contain a complete bytecode file. The \P Buffer is analyzed and + /// the \P Results are filled in. + /// @brief Analyze contents of a bytecode buffer. + void AnalyzeBytecodeBuffer( + const unsigned char* Buffer, ///< Pointer to start of bytecode buffer + unsigned BufferSize, ///< Size of the bytecode buffer + BytecodeAnalysis& Results, ///< The results of the analysis + std::string* ErrorStr = 0 ///< Errors, if any. + ); + + /// This function prints the contents of rhe BytecodeAnalysis structure in + /// a human legible form. + /// @brief Print BytecodeAnalysis structure to an ostream + void PrintBytecodeAnalysis(BytecodeAnalysis& bca, std::ostream& Out ); + + } // End llvm namespace + + #endif From llvm at cs.uiuc.edu Mon Jun 7 12:59:12 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Mon Jun 7 12:59:12 2004 Subject: [llvm-commits] CVS: llvm/tools/Makefile Message-ID: <200406071753.MAA21488@zion.cs.uiuc.edu> Changes in directory llvm/tools: Makefile updated: 1.28 -> 1.29 --- Log message: Commit For New Tool: llvm-abcd (Analysis of ByteCode Dumper). This tool will (eventually) provide statistical analysis of bytecode files as well as the ability to dump them in a low level format (slot numbers not resolved). The purpose of this is to aid in the Type!=Value change of bug 122: http://llvm.cs.uiuc.edu/PR122 . With this initial release, llvm-abcd merely dumps out the bytecode. However, the infrastructure for separating bytecode parsing from handling the parsing events is in place. The style chosen is similar to SAX XML parsing where a handler object is called to handlign the parsing events. This probably isn't useful to anyone but me right now as there is no analysis yet, and the dumper doesn't work on every bytecode file. It will probably be useful by the end of this week. Note that there is some duplication of code from the bytecode reader. This was done to eliminate errors from being introduced in the reader and to minimize the impact to other LLVM developers. At some point, the Analyzer and the Reader will be integrated to use the same infrastructure. Also, sorry for the minor change to Instruction.h but I just couldn't bring myself to write code that depends on Instruction internals. --- Diffs of the changes: (+2 -1) Index: llvm/tools/Makefile diff -u llvm/tools/Makefile:1.28 llvm/tools/Makefile:1.29 --- llvm/tools/Makefile:1.28 Tue Jun 1 18:49:55 2004 +++ llvm/tools/Makefile Mon Jun 7 12:53:43 2004 @@ -9,7 +9,8 @@ LEVEL := .. PARALLEL_DIRS := llvm-as llvm-dis opt gccas llc llvm-link lli gccld llvm-stub \ - analyze extract bugpoint llvm-nm llvm-prof llvm-db llvm-ar + analyze extract bugpoint llvm-nm llvm-prof llvm-db llvm-ar \ + llvm-abcd include $(LEVEL)/Makefile.common From llvm at cs.uiuc.edu Mon Jun 7 12:59:15 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Mon Jun 7 12:59:15 2004 Subject: [llvm-commits] CVS: llvm/tools/llvm-abcd/Makefile llvm-abcd.cpp Message-ID: <200406071753.MAA21505@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-abcd: Makefile added (r1.1) llvm-abcd.cpp added (r1.1) --- Log message: Commit For New Tool: llvm-abcd (Analysis of ByteCode Dumper). This tool will (eventually) provide statistical analysis of bytecode files as well as the ability to dump them in a low level format (slot numbers not resolved). The purpose of this is to aid in the Type!=Value change of bug 122: http://llvm.cs.uiuc.edu/PR122 . With this initial release, llvm-abcd merely dumps out the bytecode. However, the infrastructure for separating bytecode parsing from handling the parsing events is in place. The style chosen is similar to SAX XML parsing where a handler object is called to handlign the parsing events. This probably isn't useful to anyone but me right now as there is no analysis yet, and the dumper doesn't work on every bytecode file. It will probably be useful by the end of this week. Note that there is some duplication of code from the bytecode reader. This was done to eliminate errors from being introduced in the reader and to minimize the impact to other LLVM developers. At some point, the Analyzer and the Reader will be integrated to use the same infrastructure. Also, sorry for the minor change to Instruction.h but I just couldn't bring myself to write code that depends on Instruction internals. --- Diffs of the changes: (+128 -0) Index: llvm/tools/llvm-abcd/Makefile diff -c /dev/null llvm/tools/llvm-abcd/Makefile:1.1 *** /dev/null Mon Jun 7 12:53:53 2004 --- llvm/tools/llvm-abcd/Makefile Mon Jun 7 12:53:43 2004 *************** *** 0 **** --- 1,13 ---- + ##===- tools/llvm-abcd/Makefile ----------------------------*- Makefile -*-===## + # + # The LLVM Compiler Infrastructure + # + # This file was developed by Reid Spencer and is distributed under the + # University of Illinois Open Source License. See LICENSE.TXT for details. + # + ##===----------------------------------------------------------------------===## + LEVEL = ../.. + + TOOLNAME = llvm-abcd + USEDLIBS = bcanalyzer vmcore support.a + include $(LEVEL)/Makefile.common Index: llvm/tools/llvm-abcd/llvm-abcd.cpp diff -c /dev/null llvm/tools/llvm-abcd/llvm-abcd.cpp:1.1 *** /dev/null Mon Jun 7 12:53:53 2004 --- llvm/tools/llvm-abcd/llvm-abcd.cpp Mon Jun 7 12:53:43 2004 *************** *** 0 **** --- 1,115 ---- + //===-- llvm-dis.cpp - The low-level LLVM disassembler --------------------===// + // + // 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 utility may be invoked in the following manner: + // llvm-dis [options] - Read LLVM bytecode from stdin, write asm to stdout + // llvm-dis [options] x.bc - Read LLVM bytecode from the x.bc file, write asm + // to the x.ll file. + // Options: + // --help - Output information about command line switches + // -c - Print C code instead of LLVM assembly + // + //===----------------------------------------------------------------------===// + + #include "llvm/Bytecode/Analyzer.h" + #include "Support/CommandLine.h" + #include "llvm/System/Signals.h" + #include + #include + + using namespace llvm; + + static cl::opt + InputFilename(cl::Positional, cl::desc(""), cl::init("-")); + + static cl::opt + OutputFilename("o", cl::desc("Override output filename"), + cl::value_desc("filename")); + + static cl::opt Force ("f", cl::desc("Overwrite output files")); + static cl::opt Detailed ("d", cl::desc("Detailed output")); + + int + main(int argc, char **argv) + { + cl::ParseCommandLineOptions(argc, argv, + " llvm-abcd Analysis of ByteCode Dumper\n"); + + PrintStackTraceOnErrorSignal(); + + std::ostream* Out = &std::cout; // Default to printing to stdout... + std::istream* In = &std::cin; // Default to reading stdin + std::string ErrorMessage; + BytecodeAnalysis bca; + + /// Analyze the bytecode file + AnalyzeBytecodeFile(InputFilename, bca, &ErrorMessage); + + // If there was an error, print it and stop. + if ( ErrorMessage.size() ) { + std::cerr << argv[0] << ": " << ErrorMessage << "\n"; + return 1; + } + + // Figure out where the output is going + if (OutputFilename != "") { // Specified an output filename? + if (OutputFilename != "-") { // Not stdout? + if (!Force && std::ifstream(OutputFilename.c_str())) { + // If force is not specified, make sure not to overwrite a file! + std::cerr << argv[0] << ": error opening '" << OutputFilename + << "': file exists! Sending to standard output.\n"; + } else { + Out = new std::ofstream(OutputFilename.c_str()); + } + } + } else { + if (InputFilename == "-") { + OutputFilename = "-"; + } else { + std::string IFN = InputFilename; + int Len = IFN.length(); + if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') { + // Source ends in .bc + OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".abc"; + } else { + OutputFilename = IFN+".abc"; + } + + if (!Force && std::ifstream(OutputFilename.c_str())) { + // If force is not specified, make sure not to overwrite a file! + std::cerr << argv[0] << ": error opening '" << OutputFilename + << "': file exists! Sending to standard output.\n"; + } else { + Out = new std::ofstream(OutputFilename.c_str()); + + // Make sure that the Out file gets unlinked from the disk if we get a + // SIGINT + RemoveFileOnSignal(OutputFilename); + } + } + } + + if (!Out->good()) { + std::cerr << argv[0] << ": error opening " << OutputFilename + << ": sending to stdout instead!\n"; + Out = &std::cout; + } + + // All that abcd does is write the gathered statistics to the output + bca.dumpBytecode = true; + PrintBytecodeAnalysis(bca,*Out); + + if (Out != &std::cout) { + ((std::ofstream*)Out)->close(); + delete Out; + } + return 0; + } + + // vim: sw=2 From llvm at cs.uiuc.edu Mon Jun 7 12:59:20 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Mon Jun 7 12:59:20 2004 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Analyzer/Analyzer.cpp AnalyzerInternals.h AnalyzerWrappers.cpp BytecodeHandler.cpp BytecodeHandler.h Dumper.cpp Makefile Parser.cpp Parser.h ReaderPrimitives.h Message-ID: <200406071753.MAA21515@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Analyzer: Analyzer.cpp added (r1.1) AnalyzerInternals.h added (r1.1) AnalyzerWrappers.cpp added (r1.1) BytecodeHandler.cpp added (r1.1) BytecodeHandler.h added (r1.1) Dumper.cpp added (r1.1) Makefile added (r1.1) Parser.cpp added (r1.1) Parser.h added (r1.1) ReaderPrimitives.h added (r1.1) --- Log message: Commit For New Tool: llvm-abcd (Analysis of ByteCode Dumper). This tool will (eventually) provide statistical analysis of bytecode files as well as the ability to dump them in a low level format (slot numbers not resolved). The purpose of this is to aid in the Type!=Value change of bug 122: http://llvm.cs.uiuc.edu/PR122 . With this initial release, llvm-abcd merely dumps out the bytecode. However, the infrastructure for separating bytecode parsing from handling the parsing events is in place. The style chosen is similar to SAX XML parsing where a handler object is called to handlign the parsing events. This probably isn't useful to anyone but me right now as there is no analysis yet, and the dumper doesn't work on every bytecode file. It will probably be useful by the end of this week. Note that there is some duplication of code from the bytecode reader. This was done to eliminate errors from being introduced in the reader and to minimize the impact to other LLVM developers. At some point, the Analyzer and the Reader will be integrated to use the same infrastructure. Also, sorry for the minor change to Instruction.h but I just couldn't bring myself to write code that depends on Instruction internals. --- Diffs of the changes: (+2462 -0) Index: llvm/lib/Bytecode/Analyzer/Analyzer.cpp diff -c /dev/null llvm/lib/Bytecode/Analyzer/Analyzer.cpp:1.1 *** /dev/null Mon Jun 7 12:53:53 2004 --- llvm/lib/Bytecode/Analyzer/Analyzer.cpp Mon Jun 7 12:53:43 2004 *************** *** 0 **** --- 1,242 ---- + //===-- BytecodeHandler.cpp - Parsing Handler -------------------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Reid Spencer and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This header file defines the BytecodeHandler class that gets called by the + // AbstractBytecodeParser when parsing events occur. + // + //===----------------------------------------------------------------------===// + + #include "AnalyzerInternals.h" + + using namespace llvm; + + + namespace { + + class AnalyzerHandler : public BytecodeHandler { + public: + bool handleError(const std::string& str ) + { + return false; + } + + void handleStart() + { + } + + void handleFinish() + { + } + + void handleModuleBegin(const std::string& id) + { + } + + void handleModuleEnd(const std::string& id) + { + } + + void handleVersionInfo( + unsigned char RevisionNum, ///< Byte code revision number + Module::Endianness Endianness, ///< Endianness indicator + Module::PointerSize PointerSize ///< PointerSize indicator + ) + { + } + + void handleModuleGlobalsBegin() + { + } + + void handleGlobalVariable( + const Type* ElemType, ///< The type of the global variable + bool isConstant, ///< Whether the GV is constant or not + GlobalValue::LinkageTypes ///< The linkage type of the GV + ) + { + } + + void handleInitializedGV( + const Type* ElemType, ///< The type of the global variable + bool isConstant, ///< Whether the GV is constant or not + GlobalValue::LinkageTypes,///< The linkage type of the GV + unsigned initSlot ///< Slot number of GV's initializer + ) + { + } + + virtual void handleType( const Type* Ty ) + { + } + + void handleFunctionDeclaration( + const Type* FuncType ///< The type of the function + ) + { + } + + void handleModuleGlobalsEnd() + { + } + + void handleCompactionTableBegin() + { + } + + void handleCompactionTablePlane( + unsigned Ty, + unsigned NumEntries + ) + { + } + + void handleCompactionTableType( + unsigned i, + unsigned TypSlot, + const Type* + ) + { + } + + void handleCompactionTableValue( + unsigned i, + unsigned ValSlot, + const Type* + ) + { + } + + void handleCompactionTableEnd() + { + } + + void handleSymbolTableBegin() + { + } + + void handleSymbolTablePlane( + unsigned Ty, + unsigned NumEntries, + const Type* Typ + ) + { + } + + void handleSymbolTableType( + unsigned i, + unsigned slot, + const std::string& name + ) + { + } + + void handleSymbolTableValue( + unsigned i, + unsigned slot, + const std::string& name + ) + { + } + + void handleSymbolTableEnd() + { + } + + void handleFunctionBegin( + const Type* FType, + GlobalValue::LinkageTypes linkage + ) + { + } + + void handleFunctionEnd( + const Type* FType + ) + { + } + + void handleBasicBlockBegin( + unsigned blocknum + ) + { + } + + bool handleInstruction( + unsigned Opcode, + const Type* iType, + std::vector& Operands + ) + { + return false; + } + + void handleBasicBlockEnd(unsigned blocknum) + { + } + + void handleGlobalConstantsBegin() + { + } + + void handleConstantExpression( + unsigned Opcode, + const Type* Typ, + std::vector > ArgVec + ) + { + } + + void handleConstantValue( Constant * c ) + { + } + + void handleConstantArray( + const ArrayType* AT, + std::vector& Elements ) + { + } + + void handleConstantStruct( + const StructType* ST, + std::vector& ElementSlots) + { + } + + void handleConstantPointer( + const PointerType* PT, unsigned Slot) + { + } + + void handleConstantString( const ConstantArray* CA ) + { + } + + + void handleGlobalConstantsEnd() + { + } + + }; + + } + + void llvm::BytecodeAnalyzer::AnalyzeBytecode( + const unsigned char *Buf, + unsigned Length, + BytecodeAnalysis& bca, + const std::string &ModuleID + ) + { + AnalyzerHandler TheHandler; + AbstractBytecodeParser TheParser(&TheHandler); + TheParser.ParseBytecode( Buf, Length, ModuleID ); + TheParser.ParseAllFunctionBodies(); + } + + // vim: sw=2 Index: llvm/lib/Bytecode/Analyzer/AnalyzerInternals.h diff -c /dev/null llvm/lib/Bytecode/Analyzer/AnalyzerInternals.h:1.1 *** /dev/null Mon Jun 7 12:53:53 2004 --- llvm/lib/Bytecode/Analyzer/AnalyzerInternals.h Mon Jun 7 12:53:43 2004 *************** *** 0 **** --- 1,65 ---- + //===-- ReaderInternals.h - Definitions internal to the reader --*- C++ -*-===// + // + // 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 header file defines various stuff that is used by the bytecode reader. + // + //===----------------------------------------------------------------------===// + + #ifndef ANALYZER_INTERNALS_H + #define ANALYZER_INTERNALS_H + + #include "Parser.h" + #include "llvm/Bytecode/Analyzer.h" + + // Enable to trace to figure out what the heck is going on when parsing fails + //#define TRACE_LEVEL 10 + //#define DEBUG_OUTPUT + + #if TRACE_LEVEL // ByteCodeReading_TRACEr + #define BCR_TRACE(n, X) \ + if (n < TRACE_LEVEL) std::cerr << std::string(n*2, ' ') << X + #else + #define BCR_TRACE(n, X) + #endif + + namespace llvm { + + class BytecodeAnalyzer { + BytecodeAnalyzer(const BytecodeAnalyzer &); // DO NOT IMPLEMENT + void operator=(const BytecodeAnalyzer &); // DO NOT IMPLEMENT + public: + BytecodeAnalyzer() { } + ~BytecodeAnalyzer() { } + + void AnalyzeBytecode( + const unsigned char *Buf, + unsigned Length, + BytecodeAnalysis& bca, + const std::string &ModuleID + ); + + void DumpBytecode( + const unsigned char *Buf, + unsigned Length, + BytecodeAnalysis& bca, + const std::string &ModuleID + ); + + void dump() const { + std::cerr << "BytecodeParser instance!\n"; + } + private: + BytecodeAnalysis TheAnalysis; + }; + + } // End llvm namespace + + #endif + + // vim: sw=2 Index: llvm/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp diff -c /dev/null llvm/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp:1.1 *** /dev/null Mon Jun 7 12:53:53 2004 --- llvm/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp Mon Jun 7 12:53:43 2004 *************** *** 0 **** --- 1,208 ---- + //===- AnalyzerWrappers.cpp - Analyze bytecode from file or buffer -------===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Reid Spencer and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This file implements loading and analysis of a bytecode file and analyzing a + // bytecode buffer. + // + //===----------------------------------------------------------------------===// + + #include "llvm/Bytecode/Analyzer.h" + #include "AnalyzerInternals.h" + #include "Support/FileUtilities.h" + #include "Support/StringExtras.h" + #include "Config/unistd.h" + #include + + using namespace llvm; + + //===----------------------------------------------------------------------===// + // BytecodeFileAnalyzer - Analyze from an mmap'able file descriptor. + // + + namespace { + /// BytecodeFileAnalyzer - parses a bytecode file from a file + class BytecodeFileAnalyzer : public BytecodeAnalyzer { + private: + unsigned char *Buffer; + unsigned Length; + + BytecodeFileAnalyzer(const BytecodeFileAnalyzer&); // Do not implement + void operator=(const BytecodeFileAnalyzer &BFR); // Do not implement + + public: + BytecodeFileAnalyzer(const std::string &Filename, BytecodeAnalysis& bca); + ~BytecodeFileAnalyzer(); + }; + } + + static std::string ErrnoMessage (int savedErrNum, std::string descr) { + return ::strerror(savedErrNum) + std::string(", while trying to ") + descr; + } + + BytecodeFileAnalyzer::BytecodeFileAnalyzer(const std::string &Filename, + BytecodeAnalysis& bca) { + Buffer = (unsigned char*)ReadFileIntoAddressSpace(Filename, Length); + if (Buffer == 0) + throw "Error reading file '" + Filename + "'."; + + try { + // Parse the bytecode we mmapped in + if ( bca.dumpBytecode ) + DumpBytecode(Buffer, Length, bca, Filename); + AnalyzeBytecode(Buffer, Length, bca, Filename); + } catch (...) { + UnmapFileFromAddressSpace(Buffer, Length); + throw; + } + } + + BytecodeFileAnalyzer::~BytecodeFileAnalyzer() { + // Unmmap the bytecode... + UnmapFileFromAddressSpace(Buffer, Length); + } + + //===----------------------------------------------------------------------===// + // BytecodeBufferAnalyzer - Read from a memory buffer + // + + namespace { + /// BytecodeBufferAnalyzer - parses a bytecode file from a buffer + /// + class BytecodeBufferAnalyzer : public BytecodeAnalyzer { + private: + const unsigned char *Buffer; + bool MustDelete; + + BytecodeBufferAnalyzer(const BytecodeBufferAnalyzer&); // Do not implement + void operator=(const BytecodeBufferAnalyzer &BFR); // Do not implement + + public: + BytecodeBufferAnalyzer(const unsigned char *Buf, unsigned Length, + BytecodeAnalysis& bca, const std::string &ModuleID); + ~BytecodeBufferAnalyzer(); + + }; + } + + BytecodeBufferAnalyzer::BytecodeBufferAnalyzer(const unsigned char *Buf, + unsigned Length, + BytecodeAnalysis& bca, + const std::string &ModuleID) { + // If not aligned, allocate a new buffer to hold the bytecode... + const unsigned char *ParseBegin = 0; + if ((intptr_t)Buf & 3) { + Buffer = new unsigned char[Length+4]; + unsigned Offset = 4 - ((intptr_t)Buffer & 3); // Make sure it's aligned + ParseBegin = Buffer + Offset; + memcpy((unsigned char*)ParseBegin, Buf, Length); // Copy it over + MustDelete = true; + } else { + // If we don't need to copy it over, just use the caller's copy + ParseBegin = Buffer = Buf; + MustDelete = false; + } + try { + if ( bca.dumpBytecode ) + DumpBytecode(ParseBegin, Length, bca, ModuleID); + AnalyzeBytecode(ParseBegin, Length, bca, ModuleID); + } catch (...) { + if (MustDelete) delete [] Buffer; + throw; + } + } + + BytecodeBufferAnalyzer::~BytecodeBufferAnalyzer() { + if (MustDelete) delete [] Buffer; + } + + //===----------------------------------------------------------------------===// + // BytecodeStdinAnalyzer - Read bytecode from Standard Input + // + + namespace { + /// BytecodeStdinAnalyzer - parses a bytecode file from stdin + /// + class BytecodeStdinAnalyzer : public BytecodeAnalyzer { + private: + std::vector FileData; + unsigned char *FileBuf; + + BytecodeStdinAnalyzer(const BytecodeStdinAnalyzer&); // Do not implement + void operator=(const BytecodeStdinAnalyzer &BFR); // Do not implement + + public: + BytecodeStdinAnalyzer(BytecodeAnalysis& bca); + }; + } + + BytecodeStdinAnalyzer::BytecodeStdinAnalyzer(BytecodeAnalysis& bca ) { + int BlockSize; + unsigned char Buffer[4096*4]; + + // Read in all of the data from stdin, we cannot mmap stdin... + while ((BlockSize = ::read(0 /*stdin*/, Buffer, 4096*4))) { + if (BlockSize == -1) + throw ErrnoMessage(errno, "read from standard input"); + + FileData.insert(FileData.end(), Buffer, Buffer+BlockSize); + } + + if (FileData.empty()) + throw std::string("Standard Input empty!"); + + FileBuf = &FileData[0]; + if (bca.dumpBytecode) + DumpBytecode(&FileData[0], FileData.size(), bca, ""); + AnalyzeBytecode(FileBuf, FileData.size(), bca, ""); + } + + //===----------------------------------------------------------------------===// + // Wrapper functions + //===----------------------------------------------------------------------===// + + // AnalyzeBytecodeFile - analyze one file + void llvm::AnalyzeBytecodeFile(const std::string &Filename, + BytecodeAnalysis& bca, + std::string *ErrorStr) + { + try { + if ( Filename != "-" ) + BytecodeFileAnalyzer bfa(Filename,bca); + else + BytecodeStdinAnalyzer bsa(bca); + } catch (std::string &err) { + if (ErrorStr) *ErrorStr = err; + } + } + + // AnalyzeBytecodeBuffer - analyze a buffer + void llvm::AnalyzeBytecodeBuffer( + const unsigned char* Buffer, ///< Pointer to start of bytecode buffer + unsigned BufferSize, ///< Size of the bytecode buffer + BytecodeAnalysis& Results, ///< The results of the analysis + std::string* ErrorStr ///< Errors, if any. + ) + { + try { + BytecodeBufferAnalyzer(Buffer, BufferSize, Results, "" ); + } catch (std::string& err ) { + if ( ErrorStr) *ErrorStr = err; + } + } + + + /// This function prints the contents of rhe BytecodeAnalysis structure in + /// a human legible form. + /// @brief Print BytecodeAnalysis structure to an ostream + void llvm::PrintBytecodeAnalysis(BytecodeAnalysis& bca, std::ostream& Out ) + { + Out << "Not Implemented Yet.\n"; + } + + // vim: sw=2 Index: llvm/lib/Bytecode/Analyzer/BytecodeHandler.cpp diff -c /dev/null llvm/lib/Bytecode/Analyzer/BytecodeHandler.cpp:1.1 *** /dev/null Mon Jun 7 12:53:53 2004 --- llvm/lib/Bytecode/Analyzer/BytecodeHandler.cpp Mon Jun 7 12:53:43 2004 *************** *** 0 **** --- 1,220 ---- + //===-- BytecodeHandler.cpp - Parsing Handler -------------------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Reid Spencer and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This header file defines the BytecodeHandler class that gets called by the + // AbstractBytecodeParser when parsing events occur. + // + //===----------------------------------------------------------------------===// + + #include "BytecodeHandler.h" + + using namespace llvm; + + bool BytecodeHandler::handleError(const std::string& str ) + { + return false; + } + + void BytecodeHandler::handleStart() + { + } + + void BytecodeHandler::handleFinish() + { + } + + void BytecodeHandler::handleModuleBegin(const std::string& id) + { + } + + void BytecodeHandler::handleModuleEnd(const std::string& id) + { + } + + void BytecodeHandler::handleVersionInfo( + unsigned char RevisionNum, ///< Byte code revision number + Module::Endianness Endianness, ///< Endianness indicator + Module::PointerSize PointerSize ///< PointerSize indicator + ) + { + } + + void BytecodeHandler::handleModuleGlobalsBegin() + { + } + + void BytecodeHandler::handleGlobalVariable( + const Type* ElemType, ///< The type of the global variable + bool isConstant, ///< Whether the GV is constant or not + GlobalValue::LinkageTypes ///< The linkage type of the GV + ) + { + } + + void BytecodeHandler::handleInitializedGV( + const Type* ElemType, ///< The type of the global variable + bool isConstant, ///< Whether the GV is constant or not + GlobalValue::LinkageTypes,///< The linkage type of the GV + unsigned initSlot ///< Slot number of GV's initializer + ) + { + } + + void BytecodeHandler::handleType( const Type* Ty ) + { + } + + void BytecodeHandler::handleFunctionDeclaration( + const Type* FuncType ///< The type of the function + ) + { + } + + void BytecodeHandler::handleModuleGlobalsEnd() + { + } + + void BytecodeHandler::handleCompactionTableBegin() + { + } + + void BytecodeHandler::handleCompactionTablePlane( + unsigned Ty, + unsigned NumEntries + ) + { + } + + void BytecodeHandler::handleCompactionTableType( + unsigned i, + unsigned TypSlot, + const Type* + ) + { + } + + void BytecodeHandler::handleCompactionTableValue( + unsigned i, + unsigned ValSlot, + const Type* + ) + { + } + + void BytecodeHandler::handleCompactionTableEnd() + { + } + + void BytecodeHandler::handleSymbolTableBegin() + { + } + + void BytecodeHandler::handleSymbolTablePlane( + unsigned Ty, + unsigned NumEntries, + const Type* Typ + ) + { + } + + void BytecodeHandler::handleSymbolTableType( + unsigned i, + unsigned slot, + const std::string& name + ) + { + } + + void BytecodeHandler::handleSymbolTableValue( + unsigned i, + unsigned slot, + const std::string& name + ) + { + } + + void BytecodeHandler::handleSymbolTableEnd() + { + } + + void BytecodeHandler::handleFunctionBegin( + const Type* FType, + GlobalValue::LinkageTypes linkage + ) + { + } + + void BytecodeHandler::handleFunctionEnd( + const Type* FType + ) + { + } + + void BytecodeHandler::handleBasicBlockBegin( + unsigned blocknum + ) + { + } + + bool BytecodeHandler::handleInstruction( + unsigned Opcode, + const Type* iType, + std::vector& Operands + ) + { + return false; + } + + void BytecodeHandler::handleBasicBlockEnd(unsigned blocknum) + { + } + + void BytecodeHandler::handleGlobalConstantsBegin() + { + } + + void BytecodeHandler::handleConstantExpression( + unsigned Opcode, + const Type* Typ, + std::vector > ArgVec + ) + { + } + + void BytecodeHandler::handleConstantValue( Constant * c ) + { + } + + void BytecodeHandler::handleConstantArray( + const ArrayType* AT, + std::vector& Elements ) + { + } + + void BytecodeHandler::handleConstantStruct( + const StructType* ST, + std::vector& ElementSlots) + { + } + + void BytecodeHandler::handleConstantPointer( + const PointerType* PT, unsigned Slot) + { + } + + void BytecodeHandler::handleConstantString( const ConstantArray* CA ) + { + } + + + void BytecodeHandler::handleGlobalConstantsEnd() + { + } + + // vim: sw=2 Index: llvm/lib/Bytecode/Analyzer/BytecodeHandler.h diff -c /dev/null llvm/lib/Bytecode/Analyzer/BytecodeHandler.h:1.1 *** /dev/null Mon Jun 7 12:53:53 2004 --- llvm/lib/Bytecode/Analyzer/BytecodeHandler.h Mon Jun 7 12:53:43 2004 *************** *** 0 **** --- 1,247 ---- + //===-- BytecodeHandler.h - Parsing Handler ---------------------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Reid Spencer and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This header file defines the BytecodeHandler class that gets called by the + // AbstractBytecodeParser when parsing events occur. + // + //===----------------------------------------------------------------------===// + + #ifndef BYTECODE_HANDLER_H + #define BYTECODE_HANDLER_H + + #include "llvm/Module.h" + #include "llvm/GlobalValue.h" + #include + + namespace llvm { + + class ArrayType; + class StructType; + class PointerType; + class ConstantArray; + + /// This class provides the interface for the handling bytecode events during + /// parsing. The methods on this interface are invoked by the + /// AbstractBytecodeParser as it discovers the content of a bytecode stream. + /// This class provides a a clear separation of concerns between recognizing + /// the semantic units of a bytecode file and deciding what to do with them. + /// The AbstractBytecodeParser recognizes the content of the bytecode file and + /// calls the BytecodeHandler methods to determine what should be done. This + /// arrangement allows Bytecode files to be read and handled for a number of + /// purposes simply by creating a subclass of BytecodeHandler. None of the + /// parsing details need to be understood, only the meaning of the calls + /// made on this interface. + /// + /// Another paradigm that uses this design pattern is the XML SAX Parser. The + /// ContentHandler for SAX plays the same role as the BytecodeHandler here. + /// @brief Handle Bytecode Parsing Events + class BytecodeHandler { + + /// @name Constructors And Operators + /// @{ + public: + /// @brief Default constructor (empty) + BytecodeHandler() {} + /// @brief Virtual destructor (empty) + virtual ~BytecodeHandler() {} + + private: + BytecodeHandler(const BytecodeHandler &); // DO NOT IMPLEMENT + void operator=(const BytecodeHandler &); // DO NOT IMPLEMENT + + /// @} + /// @name Handler Methods + /// @{ + public: + + /// This method is called whenever the parser detects an error in the + /// bytecode formatting. Returning true will cause the parser to keep + /// going, however this is inadvisable in most cases. Returning false will + /// cause the parser to throw the message as a std::string. + /// @brief Handle parsing errors. + virtual bool handleError(const std::string& str ); + + /// This method is called at the beginning of a parse before anything is + /// read in order to give the handler a chance to initialize. + /// @brief Handle the start of a bytecode parse + virtual void handleStart(); + + /// This method is called at the end of a parse after everything has been + /// read in order to give the handler a chance to terminate. + /// @brief Handle the end of a bytecode parse + virtual void handleFinish(); + + /// This method is called at the start of a module to indicate that a + /// module is being parsed. + /// @brief Handle the start of a module. + virtual void handleModuleBegin(const std::string& id); + + /// This method is called at the end of a module to indicate that the module + /// previously being parsed has concluded. + /// @brief Handle the end of a module. + virtual void handleModuleEnd(const std::string& id); + + /// This method is called once the version information has been parsed. It + /// provides the information about the version of the bytecode file being + /// read. + /// @brief Handle the bytecode prolog + virtual void handleVersionInfo( + unsigned char RevisionNum, ///< Byte code revision number + Module::Endianness Endianness, ///< Endianness indicator + Module::PointerSize PointerSize ///< PointerSize indicator + ); + + /// This method is called at the start of a module globals block which + /// contains the global variables and the function placeholders + virtual void handleModuleGlobalsBegin(); + + /// This method is called when a non-initialized global variable is + /// recognized. Its type, constness, and linkage type are provided. + /// @brief Handle a non-initialized global variable + virtual void handleGlobalVariable( + const Type* ElemType, ///< The type of the global variable + bool isConstant, ///< Whether the GV is constant or not + GlobalValue::LinkageTypes ///< The linkage type of the GV + ); + + /// This method is called when an initialized global variable is recognized. + /// Its type constness, linkage type, and the slot number of the initializer + /// are provided. + /// @brief Handle an intialized global variable. + virtual void handleInitializedGV( + const Type* ElemType, ///< The type of the global variable + bool isConstant, ///< Whether the GV is constant or not + GlobalValue::LinkageTypes,///< The linkage type of the GV + unsigned initSlot ///< Slot number of GV's initializer + ); + + /// This method is called when a new type is recognized. The type is + /// converted from the bytecode and passed to this method. + /// @brief Handle a type + virtual void handleType( const Type* Ty ); + + /// This method is called when the function prototype for a function is + /// encountered in the module globals block. + virtual void handleFunctionDeclaration( + const Type* FuncType ///< The type of the function + ); + + /// This method is called at the end of the module globals block. + /// @brief Handle end of module globals block. + virtual void handleModuleGlobalsEnd(); + + /// This method is called at the beginning of a compaction table. + /// @brief Handle start of compaction table. + virtual void handleCompactionTableBegin(); + virtual void handleCompactionTablePlane( + unsigned Ty, + unsigned NumEntries + ); + + virtual void handleCompactionTableType( + unsigned i, + unsigned TypSlot, + const Type* + ); + + virtual void handleCompactionTableValue( + unsigned i, + unsigned ValSlot, + const Type* + ); + + virtual void handleCompactionTableEnd(); + + virtual void handleSymbolTableBegin(); + + virtual void handleSymbolTablePlane( + unsigned Ty, + unsigned NumEntries, + const Type* Ty + ); + + virtual void handleSymbolTableType( + unsigned i, + unsigned slot, + const std::string& name + ); + + virtual void handleSymbolTableValue( + unsigned i, + unsigned slot, + const std::string& name + ); + + virtual void handleSymbolTableEnd(); + + virtual void handleFunctionBegin( + const Type* FType, + GlobalValue::LinkageTypes linkage + ); + + virtual void handleFunctionEnd( + const Type* FType + ); + + virtual void handleBasicBlockBegin( + unsigned blocknum + ); + + /// This method is called for each instruction that is parsed. + /// @returns true if the instruction is a block terminating instruction + /// @brief Handle an instruction + virtual bool handleInstruction( + unsigned Opcode, + const Type* iType, + std::vector& Operands + ); + + /// This method is called for each block that is parsed. + virtual void handleBasicBlockEnd(unsigned blocknum); + /// This method is called at the start of the global constants block. + /// @brief Handle start of global constants block. + virtual void handleGlobalConstantsBegin(); + + virtual void handleConstantExpression( + unsigned Opcode, + const Type* Typ, + std::vector > ArgVec + ); + + virtual void handleConstantArray( + const ArrayType* AT, + std::vector& ElementSlots + ); + + virtual void handleConstantStruct( + const StructType* ST, + std::vector& ElementSlots + ); + + virtual void handleConstantPointer( + const PointerType* PT, + unsigned Slot + ); + + virtual void handleConstantString( + const ConstantArray* CA + ); + + virtual void handleConstantValue( Constant * c ); + virtual void handleGlobalConstantsEnd(); + + /// @} + + }; + + } // End llvm namespace + + #endif + + // vim: sw=2 Index: llvm/lib/Bytecode/Analyzer/Dumper.cpp diff -c /dev/null llvm/lib/Bytecode/Analyzer/Dumper.cpp:1.1 *** /dev/null Mon Jun 7 12:53:53 2004 --- llvm/lib/Bytecode/Analyzer/Dumper.cpp Mon Jun 7 12:53:43 2004 *************** *** 0 **** --- 1,311 ---- + //===-- BytecodeDumper.cpp - Parsing Handler --------------------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Reid Spencer and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This header file defines the BytecodeDumper class that gets called by the + // AbstractBytecodeParser when parsing events occur. It merely dumps the + // information presented to it from the parser. + // + //===----------------------------------------------------------------------===// + + #include "AnalyzerInternals.h" + #include "llvm/Constant.h" + #include "llvm/Constants.h" + #include "llvm/DerivedTypes.h" + #include "llvm/Instruction.h" + #include "llvm/Type.h" + + using namespace llvm; + + namespace { + + class BytecodeDumper : public llvm::BytecodeHandler { + public: + + virtual bool handleError(const std::string& str ) + { + std::cout << "ERROR: " << str << "\n"; + return true; + } + + virtual void handleStart() + { + std::cout << "Bytecode {\n"; + } + + virtual void handleFinish() + { + std::cout << "} End Bytecode\n"; + } + + virtual void handleModuleBegin(const std::string& id) + { + std::cout << " Module " << id << " {\n"; + } + + virtual void handleModuleEnd(const std::string& id) + { + std::cout << " } End Module " << id << "\n"; + } + + virtual void handleVersionInfo( + unsigned char RevisionNum, ///< Byte code revision number + Module::Endianness Endianness, ///< Endianness indicator + Module::PointerSize PointerSize ///< PointerSize indicator + ) + { + std::cout << " RevisionNum: " << int(RevisionNum) + << " Endianness: " << Endianness + << " PointerSize: " << PointerSize << "\n"; + } + + virtual void handleModuleGlobalsBegin() + { + std::cout << " BLOCK: ModuleGlobalInfo {\n"; + } + + virtual void handleGlobalVariable( + const Type* ElemType, ///< The type of the global variable + bool isConstant, ///< Whether the GV is constant or not + GlobalValue::LinkageTypes Linkage ///< The linkage type of the GV + ) + { + std::cout << " GV: Uninitialized, " + << ( isConstant? "Constant, " : "Variable, ") + << " Linkage=" << Linkage << " Type=" + << ElemType->getDescription() << "\n"; + } + + virtual void handleInitializedGV( + const Type* ElemType, ///< The type of the global variable + bool isConstant, ///< Whether the GV is constant or not + GlobalValue::LinkageTypes Linkage,///< The linkage type of the GV + unsigned initSlot ///< Slot number of GV's initializer + ) + { + std::cout << " GV: Initialized, " + << ( isConstant? "Constant, " : "Variable, ") + << " Linkage=" << Linkage << " Type=" + << ElemType->getDescription() + << " InitializerSlot=" << initSlot << "\n"; + } + + virtual void handleType( const Type* Ty ) + { + std::cout << " Type: " << Ty->getDescription() << "\n"; + } + + virtual void handleFunctionDeclaration( const Type* FuncType ) + { + std::cout << " Function: " << FuncType->getDescription() << "\n"; + } + + virtual void handleModuleGlobalsEnd() + { + std::cout << " } END BLOCK: ModuleGlobalInfo\n"; + } + + void handleCompactionTableBegin() + { + std::cout << " BLOCK: CompactionTable {\n"; + } + + virtual void handleCompactionTablePlane( unsigned Ty, unsigned NumEntries ) + { + std::cout << " Plane: Ty=" << Ty << " Size=" << NumEntries << "\n"; + } + + virtual void handleCompactionTableType( + unsigned i, + unsigned TypSlot, + const Type* Ty + ) + { + std::cout << " Type: " << i << " Slot:" << TypSlot + << " is " << Ty->getDescription() << "\n"; + } + + virtual void handleCompactionTableValue( + unsigned i, + unsigned ValSlot, + const Type* Ty + ) + { + std::cout << " Value: " << i << " Slot:" << ValSlot + << " is " << Ty->getDescription() << "\n"; + } + + virtual void handleCompactionTableEnd() + { + std::cout << " } END BLOCK: CompactionTable\n"; + } + + virtual void handleSymbolTableBegin() + { + std::cout << " BLOCK: SymbolTable {\n"; + } + + virtual void handleSymbolTablePlane( + unsigned Ty, + unsigned NumEntries, + const Type* Typ + ) + { + std::cout << " Plane: Ty=" << Ty << " Size=" << NumEntries + << " Type: " << Typ->getDescription() << "\n"; + } + + virtual void handleSymbolTableType( + unsigned i, + unsigned slot, + const std::string& name + ) + { + std::cout << " Type " << i << " Slot=" << slot + << " Name: " << name << "\n"; + } + + virtual void handleSymbolTableValue( + unsigned i, + unsigned slot, + const std::string& name + ) + { + std::cout << " Value " << i << " Slot=" << slot + << " Name: " << name << "\n"; + } + + virtual void handleSymbolTableEnd() + { + std::cout << " } END BLOCK: SymbolTable\n"; + } + + virtual void handleFunctionBegin( + const Type* FType, + GlobalValue::LinkageTypes linkage + ) + { + std::cout << " BLOCK: Function {\n"; + std::cout << " Linkage: " << linkage << "\n"; + std::cout << " Type: " << FType->getDescription() << "\n"; + } + + virtual void handleFunctionEnd( + const Type* FType + ) + { + std::cout << " } END BLOCK: Function\n"; + } + + virtual void handleBasicBlockBegin( + unsigned blocknum + ) + { + std::cout << " BLOCK: BasicBlock #" << blocknum << "{\n"; + } + + virtual bool handleInstruction( + unsigned Opcode, + const Type* iType, + std::vector& Operands + ) + { + std::cout << " INST: OpCode=" + << Instruction::getOpcodeName(Opcode) << " Type=" + << iType->getDescription() << "\n"; + for ( unsigned i = 0; i < Operands.size(); ++i ) + std::cout << " Op#" << i << " Slot=" << Operands[i] << "\n"; + + return Instruction::isTerminator(Opcode); + } + + virtual void handleBasicBlockEnd(unsigned blocknum) + { + std::cout << " } END BLOCK: BasicBlock #" << blocknum << "{\n"; + } + + virtual void handleGlobalConstantsBegin() + { + std::cout << " BLOCK: GlobalConstants {\n"; + } + + virtual void handleConstantExpression( + unsigned Opcode, + const Type* Typ, + std::vector > ArgVec + ) + { + std::cout << " EXPR: " << Instruction::getOpcodeName(Opcode) + << " Type=" << Typ->getDescription() << "\n"; + for ( unsigned i = 0; i < ArgVec.size(); ++i ) + std::cout << " Arg#" << i << " Type=" + << ArgVec[i].first->getDescription() << " Slot=" + << ArgVec[i].second << "\n"; + } + + virtual void handleConstantValue( Constant * c ) + { + std::cout << " VALUE: "; + c->print(std::cout); + std::cout << "\n"; + } + + virtual void handleConstantArray( + const ArrayType* AT, + std::vector& Elements ) + { + std::cout << " ARRAY: " << AT->getDescription() << "\n"; + for ( unsigned i = 0; i < Elements.size(); ++i ) + std::cout << " #" << i << " Slot=" << Elements[i] << "\n"; + } + + virtual void handleConstantStruct( + const StructType* ST, + std::vector& Elements) + { + std::cout << " STRUC: " << ST->getDescription() << "\n"; + for ( unsigned i = 0; i < Elements.size(); ++i ) + std::cout << " #" << i << " Slot=" << Elements[i] << "\n"; + } + + virtual void handleConstantPointer( + const PointerType* PT, unsigned Slot) + { + std::cout << " POINT: " << PT->getDescription() + << " Slot=" << Slot << "\n"; + } + + virtual void handleConstantString( const ConstantArray* CA ) + { + std::cout << " STRNG: "; + CA->print(std::cout); + std::cout << "\n"; + } + + virtual void handleGlobalConstantsEnd() + { + std::cout << " } END BLOCK: GlobalConstants\n"; + } + }; + + } + + void BytecodeAnalyzer::DumpBytecode( + const unsigned char *Buf, + unsigned Length, + BytecodeAnalysis& bca, + const std::string &ModuleID + ) + { + BytecodeDumper TheHandler; + AbstractBytecodeParser TheParser(&TheHandler); + TheParser.ParseBytecode( Buf, Length, ModuleID ); + TheParser.ParseAllFunctionBodies(); + } + + // vim: sw=2 Index: llvm/lib/Bytecode/Analyzer/Makefile diff -c /dev/null llvm/lib/Bytecode/Analyzer/Makefile:1.1 *** /dev/null Mon Jun 7 12:53:53 2004 --- llvm/lib/Bytecode/Analyzer/Makefile Mon Jun 7 12:53:43 2004 *************** *** 0 **** --- 1,13 ---- + ##===- lib/Bytecode/Reader/Makefile ------------------------*- Makefile -*-===## + # + # 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. + # + ##===----------------------------------------------------------------------===## + LEVEL = ../../.. + LIBRARYNAME = bcanalyzer + + include $(LEVEL)/Makefile.common + Index: llvm/lib/Bytecode/Analyzer/Parser.cpp diff -c /dev/null llvm/lib/Bytecode/Analyzer/Parser.cpp:1.1 *** /dev/null Mon Jun 7 12:53:53 2004 --- llvm/lib/Bytecode/Analyzer/Parser.cpp Mon Jun 7 12:53:43 2004 *************** *** 0 **** --- 1,877 ---- + //===- Reader.cpp - Code to read bytecode files ---------------------------===// + // + // 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 library implements the functionality defined in llvm/Bytecode/Reader.h + // + // Note that this library should be as fast as possible, reentrant, and + // threadsafe!! + // + // TODO: Allow passing in an option to ignore the symbol table + // + //===----------------------------------------------------------------------===// + + #include "AnalyzerInternals.h" + #include "llvm/Module.h" + #include "llvm/Bytecode/Format.h" + #include "Support/StringExtras.h" + #include + #include + + using namespace llvm; + + #define PARSE_ERROR(inserters) \ + { \ + std::ostringstream errormsg; \ + errormsg << inserters; \ + if ( ! handler->handleError( errormsg.str() ) ) \ + throw std::string(errormsg.str()); \ + } + + const Type *AbstractBytecodeParser::getType(unsigned ID) { + //cerr << "Looking up Type ID: " << ID << "\n"; + + if (ID < Type::FirstDerivedTyID) + if (const Type *T = Type::getPrimitiveType((Type::PrimitiveID)ID)) + return T; // Asked for a primitive type... + + // Otherwise, derived types need offset... + ID -= Type::FirstDerivedTyID; + + if (!CompactionTypeTable.empty()) { + if (ID >= CompactionTypeTable.size()) + PARSE_ERROR("Type ID out of range for compaction table!"); + return CompactionTypeTable[ID]; + } + + // Is it a module-level type? + if (ID < ModuleTypes.size()) + return ModuleTypes[ID].get(); + + // Nope, is it a function-level type? + ID -= ModuleTypes.size(); + if (ID < FunctionTypes.size()) + return FunctionTypes[ID].get(); + + PARSE_ERROR("Illegal type reference!"); + return Type::VoidTy; + } + + bool AbstractBytecodeParser::ParseInstruction(BufPtr& Buf, BufPtr EndBuf, + std::vector &Operands) { + Operands.clear(); + unsigned iType = 0; + unsigned Opcode = 0; + unsigned Op = read(Buf, EndBuf); + + // bits Instruction format: Common to all formats + // -------------------------- + // 01-00: Opcode type, fixed to 1. + // 07-02: Opcode + Opcode = (Op >> 2) & 63; + Operands.resize((Op >> 0) & 03); + + switch (Operands.size()) { + case 1: + // bits Instruction format: + // -------------------------- + // 19-08: Resulting type plane + // 31-20: Operand #1 (if set to (2^12-1), then zero operands) + // + iType = (Op >> 8) & 4095; + Operands[0] = (Op >> 20) & 4095; + if (Operands[0] == 4095) // Handle special encoding for 0 operands... + Operands.resize(0); + break; + case 2: + // bits Instruction format: + // -------------------------- + // 15-08: Resulting type plane + // 23-16: Operand #1 + // 31-24: Operand #2 + // + iType = (Op >> 8) & 255; + Operands[0] = (Op >> 16) & 255; + Operands[1] = (Op >> 24) & 255; + break; + case 3: + // bits Instruction format: + // -------------------------- + // 13-08: Resulting type plane + // 19-14: Operand #1 + // 25-20: Operand #2 + // 31-26: Operand #3 + // + iType = (Op >> 8) & 63; + Operands[0] = (Op >> 14) & 63; + Operands[1] = (Op >> 20) & 63; + Operands[2] = (Op >> 26) & 63; + break; + case 0: + Buf -= 4; // Hrm, try this again... + Opcode = read_vbr_uint(Buf, EndBuf); + Opcode >>= 2; + iType = read_vbr_uint(Buf, EndBuf); + + unsigned NumOperands = read_vbr_uint(Buf, EndBuf); + Operands.resize(NumOperands); + + if (NumOperands == 0) + PARSE_ERROR("Zero-argument instruction found; this is invalid."); + + for (unsigned i = 0; i != NumOperands; ++i) + Operands[i] = read_vbr_uint(Buf, EndBuf); + align32(Buf, EndBuf); + break; + } + + return handler->handleInstruction(Opcode, getType(iType), Operands); + } + + /// ParseBasicBlock - In LLVM 1.0 bytecode files, we used to output one + /// basicblock at a time. This method reads in one of the basicblock packets. + void AbstractBytecodeParser::ParseBasicBlock(BufPtr &Buf, + BufPtr EndBuf, + unsigned BlockNo) { + handler->handleBasicBlockBegin( BlockNo ); + + std::vector Args; + bool is_terminating = false; + while (Buf < EndBuf) + is_terminating = ParseInstruction(Buf, EndBuf, Args); + + if ( ! is_terminating ) + PARSE_ERROR( + "Failed to recognize instruction as terminating at end of block"); + + handler->handleBasicBlockEnd( BlockNo ); + } + + + /// ParseInstructionList - Parse all of the BasicBlock's & Instruction's in the + /// body of a function. In post 1.0 bytecode files, we no longer emit basic + /// block individually, in order to avoid per-basic-block overhead. + unsigned AbstractBytecodeParser::ParseInstructionList( BufPtr &Buf, BufPtr EndBuf) { + unsigned BlockNo = 0; + std::vector Args; + + while (Buf < EndBuf) { + handler->handleBasicBlockBegin( BlockNo ); + + // Read instructions into this basic block until we get to a terminator + bool is_terminating = false; + while (Buf < EndBuf && !is_terminating ) + is_terminating = ParseInstruction(Buf, EndBuf, Args ) ; + + if (!is_terminating) + PARSE_ERROR( "Non-terminated basic block found!"); + + handler->handleBasicBlockEnd( BlockNo ); + ++BlockNo; + } + return BlockNo; + } + + void AbstractBytecodeParser::ParseSymbolTable(BufPtr &Buf, BufPtr EndBuf) { + handler->handleSymbolTableBegin(); + + while (Buf < EndBuf) { + // Symtab block header: [num entries][type id number] + unsigned NumEntries = read_vbr_uint(Buf, EndBuf); + unsigned Typ = read_vbr_uint(Buf, EndBuf); + const Type *Ty = getType(Typ); + + handler->handleSymbolTablePlane( Typ, NumEntries, Ty ); + + for (unsigned i = 0; i != NumEntries; ++i) { + // Symtab entry: [def slot #][name] + unsigned slot = read_vbr_uint(Buf, EndBuf); + std::string Name = read_str(Buf, EndBuf); + + if (Typ == Type::TypeTyID) + handler->handleSymbolTableType( i, slot, Name ); + else + handler->handleSymbolTableValue( i, slot, Name ); + } + } + + if (Buf > EndBuf) + PARSE_ERROR("Tried to read past end of buffer while reading symbol table."); + + handler->handleSymbolTableEnd(); + } + + void AbstractBytecodeParser::ParseFunctionLazily(BufPtr &Buf, BufPtr EndBuf) { + if (FunctionSignatureList.empty()) + throw std::string("FunctionSignatureList empty!"); + + const Type *FType = FunctionSignatureList.back(); + FunctionSignatureList.pop_back(); + + // Save the information for future reading of the function + LazyFunctionLoadMap[FType] = LazyFunctionInfo(Buf, EndBuf); + // Pretend we've `parsed' this function + Buf = EndBuf; + } + + void AbstractBytecodeParser::ParseNextFunction(Type* FType) { + // Find {start, end} pointers and slot in the map. If not there, we're done. + LazyFunctionMap::iterator Fi = LazyFunctionLoadMap.find(FType); + + // Make sure we found it + if ( Fi == LazyFunctionLoadMap.end() ) { + PARSE_ERROR("Unrecognized function of type " << FType->getDescription()); + return; + } + + BufPtr Buf = Fi->second.Buf; + BufPtr EndBuf = Fi->second.EndBuf; + assert(Fi->first == FType); + + LazyFunctionLoadMap.erase(Fi); + + this->ParseFunctionBody( FType, Buf, EndBuf ); + } + + void AbstractBytecodeParser::ParseFunctionBody(const Type* FType, + BufPtr &Buf, BufPtr EndBuf ) { + + GlobalValue::LinkageTypes Linkage = GlobalValue::ExternalLinkage; + + unsigned LinkageType = read_vbr_uint(Buf, EndBuf); + switch (LinkageType) { + case 0: Linkage = GlobalValue::ExternalLinkage; break; + case 1: Linkage = GlobalValue::WeakLinkage; break; + case 2: Linkage = GlobalValue::AppendingLinkage; break; + case 3: Linkage = GlobalValue::InternalLinkage; break; + case 4: Linkage = GlobalValue::LinkOnceLinkage; break; + default: + PARSE_ERROR("Invalid linkage type for Function."); + Linkage = GlobalValue::InternalLinkage; + break; + } + + handler->handleFunctionBegin(FType,Linkage); + + // Keep track of how many basic blocks we have read in... + unsigned BlockNum = 0; + bool InsertedArguments = false; + + while (Buf < EndBuf) { + unsigned Type, Size; + BufPtr OldBuf = Buf; + readBlock(Buf, EndBuf, Type, Size); + + switch (Type) { + case BytecodeFormat::ConstantPool: + ParseConstantPool(Buf, Buf+Size, FunctionTypes ); + break; + + case BytecodeFormat::CompactionTable: + ParseCompactionTable(Buf, Buf+Size); + break; + + case BytecodeFormat::BasicBlock: + ParseBasicBlock(Buf, Buf+Size, BlockNum++); + break; + + case BytecodeFormat::InstructionList: + if (BlockNum) + PARSE_ERROR("InstructionList must come before basic blocks!"); + BlockNum = ParseInstructionList(Buf, Buf+Size); + break; + + case BytecodeFormat::SymbolTable: + ParseSymbolTable(Buf, Buf+Size ); + break; + + default: + Buf += Size; + if (OldBuf > Buf) + PARSE_ERROR("Wrapped around reading bytecode"); + break; + } + + // Malformed bc file if read past end of block. + align32(Buf, EndBuf); + } + + handler->handleFunctionEnd(FType); + + // Clear out function-level types... + FunctionTypes.clear(); + CompactionTypeTable.clear(); + } + + void AbstractBytecodeParser::ParseAllFunctionBodies() { + LazyFunctionMap::iterator Fi = LazyFunctionLoadMap.begin(); + LazyFunctionMap::iterator Fe = LazyFunctionLoadMap.end(); + + while ( Fi != Fe ) { + const Type* FType = Fi->first; + this->ParseFunctionBody(FType, Fi->second.Buf, Fi->second.EndBuf); + } + } + + void AbstractBytecodeParser::ParseCompactionTable(BufPtr &Buf, BufPtr End) { + + handler->handleCompactionTableBegin(); + + while (Buf != End) { + unsigned NumEntries = read_vbr_uint(Buf, End); + unsigned Ty; + + if ((NumEntries & 3) == 3) { + NumEntries >>= 2; + Ty = read_vbr_uint(Buf, End); + } else { + Ty = NumEntries >> 2; + NumEntries &= 3; + } + + handler->handleCompactionTablePlane( Ty, NumEntries ); + + if (Ty == Type::TypeTyID) { + for (unsigned i = 0; i != NumEntries; ++i) { + unsigned TypeSlot = read_vbr_uint(Buf,End); + const Type *Typ = getGlobalTableType(TypeSlot); + handler->handleCompactionTableType( i, TypeSlot, Typ ); + } + } else { + const Type *Typ = getType(Ty); + // Push the implicit zero + for (unsigned i = 0; i != NumEntries; ++i) { + unsigned ValSlot = read_vbr_uint(Buf, End); + handler->handleCompactionTableValue( i, ValSlot, Typ ); + } + } + } + handler->handleCompactionTableEnd(); + } + + const Type *AbstractBytecodeParser::ParseTypeConstant(const unsigned char *&Buf, + const unsigned char *EndBuf) { + unsigned PrimType = read_vbr_uint(Buf, EndBuf); + + const Type *Val = 0; + if ((Val = Type::getPrimitiveType((Type::PrimitiveID)PrimType))) + return Val; + + switch (PrimType) { + case Type::FunctionTyID: { + const Type *RetType = getType(read_vbr_uint(Buf, EndBuf)); + + unsigned NumParams = read_vbr_uint(Buf, EndBuf); + + std::vector Params; + while (NumParams--) + Params.push_back(getType(read_vbr_uint(Buf, EndBuf))); + + bool isVarArg = Params.size() && Params.back() == Type::VoidTy; + if (isVarArg) Params.pop_back(); + + Type* result = FunctionType::get(RetType, Params, isVarArg); + handler->handleType( result ); + return result; + } + case Type::ArrayTyID: { + unsigned ElTyp = read_vbr_uint(Buf, EndBuf); + const Type *ElementType = getType(ElTyp); + + unsigned NumElements = read_vbr_uint(Buf, EndBuf); + + BCR_TRACE(5, "Array Type Constant #" << ElTyp << " size=" + << NumElements << "\n"); + Type* result = ArrayType::get(ElementType, NumElements); + handler->handleType( result ); + return result; + } + case Type::StructTyID: { + std::vector Elements; + unsigned Typ = read_vbr_uint(Buf, EndBuf); + while (Typ) { // List is terminated by void/0 typeid + Elements.push_back(getType(Typ)); + Typ = read_vbr_uint(Buf, EndBuf); + } + + Type* result = StructType::get(Elements); + handler->handleType( result ); + return result; + } + case Type::PointerTyID: { + unsigned ElTyp = read_vbr_uint(Buf, EndBuf); + BCR_TRACE(5, "Pointer Type Constant #" << ElTyp << "\n"); + Type* result = PointerType::get(getType(ElTyp)); + handler->handleType( result ); + return result; + } + + case Type::OpaqueTyID: { + Type* result = OpaqueType::get(); + handler->handleType( result ); + return result; + } + + default: + PARSE_ERROR("Don't know how to deserialize primitive type" << PrimType << "\n"); + return Val; + } + } + + // ParseTypeConstants - We have to use this weird code to handle recursive + // types. We know that recursive types will only reference the current slab of + // values in the type plane, but they can forward reference types before they + // have been read. For example, Type #0 might be '{ Ty#1 }' and Type #1 might + // be 'Ty#0*'. When reading Type #0, type number one doesn't exist. To fix + // this ugly problem, we pessimistically insert an opaque type for each type we + // are about to read. This means that forward references will resolve to + // something and when we reread the type later, we can replace the opaque type + // with a new resolved concrete type. + // + void AbstractBytecodeParser::ParseTypeConstants(const unsigned char *&Buf, + const unsigned char *EndBuf, + TypeListTy &Tab, + unsigned NumEntries) { + assert(Tab.size() == 0 && "should not have read type constants in before!"); + + // Insert a bunch of opaque types to be resolved later... + Tab.reserve(NumEntries); + for (unsigned i = 0; i != NumEntries; ++i) + Tab.push_back(OpaqueType::get()); + + // Loop through reading all of the types. Forward types will make use of the + // opaque types just inserted. + // + for (unsigned i = 0; i != NumEntries; ++i) { + const Type *NewTy = ParseTypeConstant(Buf, EndBuf), *OldTy = Tab[i].get(); + if (NewTy == 0) throw std::string("Couldn't parse type!"); + BCR_TRACE(4, "#" << i << ": Read Type Constant: '" << NewTy << + "' Replacing: " << OldTy << "\n"); + + // Don't insertValue the new type... instead we want to replace the opaque + // type with the new concrete value... + // + + // Refine the abstract type to the new type. This causes all uses of the + // abstract type to use NewTy. This also will cause the opaque type to be + // deleted... + // + cast(const_cast(OldTy))->refineAbstractTypeTo(NewTy); + + // This should have replace the old opaque type with the new type in the + // value table... or with a preexisting type that was already in the system + assert(Tab[i] != OldTy && "refineAbstractType didn't work!"); + } + + BCR_TRACE(5, "Resulting types:\n"); + for (unsigned i = 0; i < NumEntries; ++i) { + BCR_TRACE(5, (void*)Tab[i].get() << " - " << Tab[i].get() << "\n"); + } + } + + + void AbstractBytecodeParser::ParseConstantValue(const unsigned char *&Buf, + const unsigned char *EndBuf, + unsigned TypeID) { + + // We must check for a ConstantExpr before switching by type because + // a ConstantExpr can be of any type, and has no explicit value. + // + // 0 if not expr; numArgs if is expr + unsigned isExprNumArgs = read_vbr_uint(Buf, EndBuf); + + if (isExprNumArgs) { + unsigned Opcode = read_vbr_uint(Buf, EndBuf); + const Type* Typ = getType(TypeID); + + // FIXME: Encoding of constant exprs could be much more compact! + std::vector > ArgVec; + ArgVec.reserve(isExprNumArgs); + + // Read the slot number and types of each of the arguments + for (unsigned i = 0; i != isExprNumArgs; ++i) { + unsigned ArgValSlot = read_vbr_uint(Buf, EndBuf); + unsigned ArgTypeSlot = read_vbr_uint(Buf, EndBuf); + BCR_TRACE(4, "CE Arg " << i << ": Type: '" << *getType(ArgTypeSlot) + << "' slot: " << ArgValSlot << "\n"); + + // Get the arg value from its slot if it exists, otherwise a placeholder + ArgVec.push_back(std::make_pair(getType(ArgTypeSlot), ArgValSlot)); + } + + handler->handleConstantExpression( Opcode, Typ, ArgVec ); + return; + } + + // Ok, not an ConstantExpr. We now know how to read the given type... + const Type *Ty = getType(TypeID); + switch (Ty->getPrimitiveID()) { + case Type::BoolTyID: { + unsigned Val = read_vbr_uint(Buf, EndBuf); + if (Val != 0 && Val != 1) + PARSE_ERROR("Invalid boolean value read."); + + handler->handleConstantValue( ConstantBool::get(Val == 1)); + break; + } + + case Type::UByteTyID: // Unsigned integer types... + case Type::UShortTyID: + case Type::UIntTyID: { + unsigned Val = read_vbr_uint(Buf, EndBuf); + if (!ConstantUInt::isValueValidForType(Ty, Val)) + throw std::string("Invalid unsigned byte/short/int read."); + handler->handleConstantValue( ConstantUInt::get(Ty, Val) ); + break; + } + + case Type::ULongTyID: { + handler->handleConstantValue( ConstantUInt::get(Ty, read_vbr_uint64(Buf, EndBuf)) ); + break; + } + + case Type::SByteTyID: // Signed integer types... + case Type::ShortTyID: + case Type::IntTyID: { + case Type::LongTyID: + int64_t Val = read_vbr_int64(Buf, EndBuf); + if (!ConstantSInt::isValueValidForType(Ty, Val)) + throw std::string("Invalid signed byte/short/int/long read."); + handler->handleConstantValue( ConstantSInt::get(Ty, Val) ); + break; + } + + case Type::FloatTyID: { + float F; + input_data(Buf, EndBuf, &F, &F+1); + handler->handleConstantValue( ConstantFP::get(Ty, F) ); + break; + } + + case Type::DoubleTyID: { + double Val; + input_data(Buf, EndBuf, &Val, &Val+1); + handler->handleConstantValue( ConstantFP::get(Ty, Val) ); + break; + } + + case Type::TypeTyID: + PARSE_ERROR("Type constants shouldn't live in constant table!"); + break; + + case Type::ArrayTyID: { + const ArrayType *AT = cast(Ty); + unsigned NumElements = AT->getNumElements(); + std::vector Elements; + Elements.reserve(NumElements); + while (NumElements--) // Read all of the elements of the constant. + Elements.push_back(read_vbr_uint(Buf, EndBuf)); + + handler->handleConstantArray( AT, Elements ); + break; + } + + case Type::StructTyID: { + const StructType *ST = cast(Ty); + std::vector Elements; + Elements.reserve(ST->getNumElements()); + for (unsigned i = 0; i != ST->getNumElements(); ++i) + Elements.push_back(read_vbr_uint(Buf, EndBuf)); + + handler->handleConstantStruct( ST, Elements ); + } + + case Type::PointerTyID: { // ConstantPointerRef value... + const PointerType *PT = cast(Ty); + unsigned Slot = read_vbr_uint(Buf, EndBuf); + handler->handleConstantPointer( PT, Slot ); + } + + default: + PARSE_ERROR("Don't know how to deserialize constant value of type '"+ + Ty->getDescription()); + } + } + + void AbstractBytecodeParser::ParseGlobalTypes(const unsigned char *&Buf, + const unsigned char *EndBuf) { + ParseConstantPool(Buf, EndBuf, ModuleTypes); + } + + void AbstractBytecodeParser::ParseStringConstants(const unsigned char *&Buf, + const unsigned char *EndBuf, + unsigned NumEntries ){ + for (; NumEntries; --NumEntries) { + unsigned Typ = read_vbr_uint(Buf, EndBuf); + const Type *Ty = getType(Typ); + if (!isa(Ty)) + throw std::string("String constant data invalid!"); + + const ArrayType *ATy = cast(Ty); + if (ATy->getElementType() != Type::SByteTy && + ATy->getElementType() != Type::UByteTy) + throw std::string("String constant data invalid!"); + + // Read character data. The type tells us how long the string is. + char Data[ATy->getNumElements()]; + input_data(Buf, EndBuf, Data, Data+ATy->getNumElements()); + + std::vector Elements(ATy->getNumElements()); + if (ATy->getElementType() == Type::SByteTy) + for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) + Elements[i] = ConstantSInt::get(Type::SByteTy, (signed char)Data[i]); + else + for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) + Elements[i] = ConstantUInt::get(Type::UByteTy, (unsigned char)Data[i]); + + // Create the constant, inserting it as needed. + ConstantArray *C = cast( ConstantArray::get(ATy, Elements) ); + handler->handleConstantString( C ); + } + } + + + void AbstractBytecodeParser::ParseConstantPool(const unsigned char *&Buf, + const unsigned char *EndBuf, + TypeListTy &TypeTab) { + while (Buf < EndBuf) { + unsigned NumEntries = read_vbr_uint(Buf, EndBuf); + unsigned Typ = read_vbr_uint(Buf, EndBuf); + if (Typ == Type::TypeTyID) { + ParseTypeConstants(Buf, EndBuf, TypeTab, NumEntries); + } else if (Typ == Type::VoidTyID) { + ParseStringConstants(Buf, EndBuf, NumEntries); + } else { + BCR_TRACE(3, "Type: '" << *getType(Typ) << "' NumEntries: " + << NumEntries << "\n"); + + for (unsigned i = 0; i < NumEntries; ++i) { + ParseConstantValue(Buf, EndBuf, Typ); + } + } + } + + if (Buf > EndBuf) PARSE_ERROR("Read past end of buffer."); + } + + void AbstractBytecodeParser::ParseModuleGlobalInfo(BufPtr &Buf, BufPtr End) { + + handler->handleModuleGlobalsBegin(); + + // Read global variables... + unsigned VarType = read_vbr_uint(Buf, End); + while (VarType != Type::VoidTyID) { // List is terminated by Void + // VarType Fields: bit0 = isConstant, bit1 = hasInitializer, bit2,3,4 = + // Linkage, bit4+ = slot# + unsigned SlotNo = VarType >> 5; + unsigned LinkageID = (VarType >> 2) & 7; + bool isConstant = VarType & 1; + bool hasInitializer = VarType & 2; + GlobalValue::LinkageTypes Linkage; + + switch (LinkageID) { + case 0: Linkage = GlobalValue::ExternalLinkage; break; + case 1: Linkage = GlobalValue::WeakLinkage; break; + case 2: Linkage = GlobalValue::AppendingLinkage; break; + case 3: Linkage = GlobalValue::InternalLinkage; break; + case 4: Linkage = GlobalValue::LinkOnceLinkage; break; + default: + PARSE_ERROR("Unknown linkage type: " << LinkageID); + Linkage = GlobalValue::InternalLinkage; + break; + } + + const Type *Ty = getType(SlotNo); + if ( !Ty ) { + PARSE_ERROR("Global has no type! SlotNo=" << SlotNo); + } + + if ( !isa(Ty)) { + PARSE_ERROR("Global not a pointer type! Ty= " << Ty->getDescription()); + } + + const Type *ElTy = cast(Ty)->getElementType(); + + // Create the global variable... + if (hasInitializer) + handler->handleGlobalVariable( ElTy, isConstant, Linkage ); + else { + unsigned initSlot = read_vbr_uint(Buf,End); + handler->handleInitializedGV( ElTy, isConstant, Linkage, initSlot ); + } + + // Get next item + VarType = read_vbr_uint(Buf, End); + } + + // Read the function objects for all of the functions that are coming + unsigned FnSignature = read_vbr_uint(Buf, End); + while (FnSignature != Type::VoidTyID) { // List is terminated by Void + const Type *Ty = getType(FnSignature); + if (!isa(Ty) || + !isa(cast(Ty)->getElementType())) { + PARSE_ERROR( "Function not a pointer to function type! Ty = " + + Ty->getDescription()); + // FIXME: what should Ty be if handler continues? + } + + // We create functions by passing the underlying FunctionType to create... + Ty = cast(Ty)->getElementType(); + + // Save this for later so we know type of lazily instantiated functions + FunctionSignatureList.push_back(Ty); + + handler->handleFunctionDeclaration(Ty); + + // Get Next function signature + FnSignature = read_vbr_uint(Buf, End); + } + + if (hasInconsistentModuleGlobalInfo) + align32(Buf, End); + + // This is for future proofing... in the future extra fields may be added that + // we don't understand, so we transparently ignore them. + // + Buf = End; + + handler->handleModuleGlobalsEnd(); + } + + void AbstractBytecodeParser::ParseVersionInfo(BufPtr &Buf, BufPtr EndBuf) { + unsigned Version = read_vbr_uint(Buf, EndBuf); + + // Unpack version number: low four bits are for flags, top bits = version + Module::Endianness Endianness; + Module::PointerSize PointerSize; + Endianness = (Version & 1) ? Module::BigEndian : Module::LittleEndian; + PointerSize = (Version & 2) ? Module::Pointer64 : Module::Pointer32; + + bool hasNoEndianness = Version & 4; + bool hasNoPointerSize = Version & 8; + + RevisionNum = Version >> 4; + + // Default values for the current bytecode version + hasInconsistentModuleGlobalInfo = false; + hasExplicitPrimitiveZeros = false; + hasRestrictedGEPTypes = false; + + switch (RevisionNum) { + case 0: // LLVM 1.0, 1.1 release version + // Base LLVM 1.0 bytecode format. + hasInconsistentModuleGlobalInfo = true; + hasExplicitPrimitiveZeros = true; + // FALL THROUGH + case 1: // LLVM 1.2 release version + // LLVM 1.2 added explicit support for emitting strings efficiently. + + // Also, it fixed the problem where the size of the ModuleGlobalInfo block + // included the size for the alignment at the end, where the rest of the + // blocks did not. + + // LLVM 1.2 and before required that GEP indices be ubyte constants for + // structures and longs for sequential types. + hasRestrictedGEPTypes = true; + + // FALL THROUGH + case 2: // LLVM 1.3 release version + break; + + default: + PARSE_ERROR("Unknown bytecode version number: " << RevisionNum); + } + + if (hasNoEndianness) Endianness = Module::AnyEndianness; + if (hasNoPointerSize) PointerSize = Module::AnyPointerSize; + + handler->handleVersionInfo(RevisionNum, Endianness, PointerSize ); + } + + void AbstractBytecodeParser::ParseModule(BufPtr &Buf, BufPtr EndBuf ) { + unsigned Type, Size; + readBlock(Buf, EndBuf, Type, Size); + if (Type != BytecodeFormat::Module || Buf+Size != EndBuf) + // Hrm, not a class? + PARSE_ERROR("Expected Module block! B: " << unsigned(intptr_t(Buf)) << + ", S: " << Size << " E: " << unsigned(intptr_t(EndBuf))); + + // Read into instance variables... + ParseVersionInfo(Buf, EndBuf); + align32(Buf, EndBuf); + + bool SeenModuleGlobalInfo = false; + bool SeenGlobalTypePlane = false; + while (Buf < EndBuf) { + BufPtr OldBuf = Buf; + readBlock(Buf, EndBuf, Type, Size); + + switch (Type) { + + case BytecodeFormat::GlobalTypePlane: + if ( SeenGlobalTypePlane ) + PARSE_ERROR("Two GlobalTypePlane Blocks Encountered!"); + + ParseGlobalTypes(Buf, Buf+Size); + SeenGlobalTypePlane = true; + break; + + case BytecodeFormat::ModuleGlobalInfo: + if ( SeenModuleGlobalInfo ) + PARSE_ERROR("Two ModuleGlobalInfo Blocks Encountered!"); + ParseModuleGlobalInfo(Buf, Buf+Size); + SeenModuleGlobalInfo = true; + break; + + case BytecodeFormat::ConstantPool: + ParseConstantPool(Buf, Buf+Size, ModuleTypes); + break; + + case BytecodeFormat::Function: + ParseFunctionLazily(Buf, Buf+Size); + break; + + case BytecodeFormat::SymbolTable: + ParseSymbolTable(Buf, Buf+Size ); + break; + + default: + Buf += Size; + if (OldBuf > Buf) + { + PARSE_ERROR("Unexpected Block of Type" << Type << "encountered!" ); + } + break; + } + align32(Buf, EndBuf); + } + } + + void AbstractBytecodeParser::ParseBytecode( + BufPtr Buf, unsigned Length, + const std::string &ModuleID) { + + handler->handleStart(); + unsigned char *EndBuf = (unsigned char*)(Buf + Length); + + // Read and check signature... + unsigned Sig = read(Buf, EndBuf); + if (Sig != ('l' | ('l' << 8) | ('v' << 16) | ('m' << 24))) { + PARSE_ERROR("Invalid bytecode signature: " << Sig); + } + + handler->handleModuleBegin(ModuleID); + + this->ParseModule(Buf, EndBuf); + + handler->handleModuleEnd(ModuleID); + + handler->handleFinish(); + } + + // vim: sw=2 Index: llvm/lib/Bytecode/Analyzer/Parser.h diff -c /dev/null llvm/lib/Bytecode/Analyzer/Parser.h:1.1 *** /dev/null Mon Jun 7 12:53:53 2004 --- llvm/lib/Bytecode/Analyzer/Parser.h Mon Jun 7 12:53:43 2004 *************** *** 0 **** --- 1,178 ---- + //===-- Parser.h - Definitions internal to the reader -----------*- C++ -*-===// + // + // The LLVM Compiler Infrastructure + // + // This file was developed by Reid Spencer and is distributed under the + // University of Illinois Open Source License. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // This header file defines the interface to the Bytecode Parser + // + //===----------------------------------------------------------------------===// + + #ifndef BYTECODE_PARSER_H + #define BYTECODE_PARSER_H + + #include "ReaderPrimitives.h" + #include "BytecodeHandler.h" + #include "llvm/Constants.h" + #include "llvm/DerivedTypes.h" + #include + #include + #include + + namespace llvm { + + struct LazyFunctionInfo { + const unsigned char *Buf, *EndBuf; + LazyFunctionInfo(const unsigned char *B = 0, const unsigned char *EB = 0) + : Buf(B), EndBuf(EB) {} + }; + + typedef std::map LazyFunctionMap; + + class AbstractBytecodeParser { + AbstractBytecodeParser(const AbstractBytecodeParser &); // DO NOT IMPLEMENT + void operator=(const AbstractBytecodeParser &); // DO NOT IMPLEMENT + public: + AbstractBytecodeParser( BytecodeHandler* h ) { handler = h; } + ~AbstractBytecodeParser() { } + + void ParseBytecode(const unsigned char *Buf, unsigned Length, + const std::string &ModuleID); + + void dump() const { + std::cerr << "AbstractBytecodeParser instance!\n"; + } + + private: + // Information about the module, extracted from the bytecode revision number. + unsigned char RevisionNum; // The rev # itself + + // Flags to distinguish LLVM 1.0 & 1.1 bytecode formats (revision #0) + + // Revision #0 had an explicit alignment of data only for the ModuleGlobalInfo + // block. This was fixed to be like all other blocks in 1.2 + bool hasInconsistentModuleGlobalInfo; + + // Revision #0 also explicitly encoded zero values for primitive types like + // int/sbyte/etc. + bool hasExplicitPrimitiveZeros; + + // Flags to control features specific the LLVM 1.2 and before (revision #1) + + // LLVM 1.2 and earlier required that getelementptr structure indices were + // ubyte constants and that sequential type indices were longs. + bool hasRestrictedGEPTypes; + + + /// CompactionTable - If a compaction table is active in the current function, + /// this is the mapping that it contains. + std::vector CompactionTypeTable; + + // ConstantFwdRefs - This maintains a mapping between 's and + // forward references to constants. Such values may be referenced before they + // are defined, and if so, the temporary object that they represent is held + // here. + // + typedef std::map, Constant*> ConstantRefsType; + ConstantRefsType ConstantFwdRefs; + + // TypesLoaded - This vector mirrors the Values[TypeTyID] plane. It is used + // to deal with forward references to types. + // + typedef std::vector TypeListTy; + TypeListTy ModuleTypes; + TypeListTy FunctionTypes; + + // When the ModuleGlobalInfo section is read, we create a FunctionType object + // for each function in the module. When the function is loaded, this type is + // used to instantiate the actual function object. + std::vector FunctionSignatureList; + + // Constant values are read in after global variables. Because of this, we + // must defer setting the initializers on global variables until after module + // level constants have been read. In the mean time, this list keeps track of + // what we must do. + // + std::vector > GlobalInits; + + // For lazy reading-in of functions, we need to save away several pieces of + // information about each function: its begin and end pointer in the buffer + // and its FunctionSlot. + // + LazyFunctionMap LazyFunctionLoadMap; + + /// The handler for parsing + BytecodeHandler* handler; + + private: + const Type *AbstractBytecodeParser::getType(unsigned ID); + /// getGlobalTableType - This is just like getType, but when a compaction + /// table is in use, it is ignored. Also, no forward references or other + /// fancy features are supported. + const Type *getGlobalTableType(unsigned Slot) { + if (Slot < Type::FirstDerivedTyID) { + const Type *Ty = Type::getPrimitiveType((Type::PrimitiveID)Slot); + assert(Ty && "Not a primitive type ID?"); + return Ty; + } + Slot -= Type::FirstDerivedTyID; + if (Slot >= ModuleTypes.size()) + throw std::string("Illegal compaction table type reference!"); + return ModuleTypes[Slot]; + } + + unsigned getGlobalTableTypeSlot(const Type *Ty) { + if (Ty->isPrimitiveType()) + return Ty->getPrimitiveID(); + TypeListTy::iterator I = find(ModuleTypes.begin(), + ModuleTypes.end(), Ty); + if (I == ModuleTypes.end()) + throw std::string("Didn't find type in ModuleTypes."); + return Type::FirstDerivedTyID + (&*I - &ModuleTypes[0]); + } + + public: + typedef const unsigned char* BufPtr; + void ParseModule (BufPtr &Buf, BufPtr End); + void ParseNextFunction (Type* FType) ; + void ParseAllFunctionBodies (); + + private: + void ParseVersionInfo (BufPtr &Buf, BufPtr End); + void ParseModuleGlobalInfo (BufPtr &Buf, BufPtr End); + void ParseSymbolTable (BufPtr &Buf, BufPtr End); + void ParseFunctionLazily (BufPtr &Buf, BufPtr End); + void ParseFunctionBody (const Type* FType, BufPtr &Buf, BufPtr EndBuf); + void ParseCompactionTable (BufPtr &Buf, BufPtr End); + void ParseGlobalTypes (BufPtr &Buf, BufPtr End); + + void ParseBasicBlock (BufPtr &Buf, BufPtr End, unsigned BlockNo); + unsigned ParseInstructionList(BufPtr &Buf, BufPtr End); + + bool ParseInstruction (BufPtr &Buf, BufPtr End, + std::vector& Args); + + void ParseConstantPool (BufPtr &Buf, BufPtr End, TypeListTy& List); + void ParseConstantValue (BufPtr &Buf, BufPtr End, unsigned TypeID); + void ParseTypeConstants (BufPtr &Buf, BufPtr End, TypeListTy &Tab, + unsigned NumEntries); + const Type *ParseTypeConstant(BufPtr &Buf, BufPtr End); + void ParseStringConstants (BufPtr &Buf, BufPtr End, unsigned NumEntries); + + }; + + + static inline void readBlock(const unsigned char *&Buf, + const unsigned char *EndBuf, + unsigned &Type, unsigned &Size) { + Type = read(Buf, EndBuf); + Size = read(Buf, EndBuf); + } + + } // End llvm namespace + + #endif + // vim: sw=2 Index: llvm/lib/Bytecode/Analyzer/ReaderPrimitives.h diff -c /dev/null llvm/lib/Bytecode/Analyzer/ReaderPrimitives.h:1.1 *** /dev/null Mon Jun 7 12:53:53 2004 --- llvm/lib/Bytecode/Analyzer/ReaderPrimitives.h Mon Jun 7 12:53:43 2004 *************** *** 0 **** --- 1,101 ---- + //===-- ReaderPrimitives.h - Bytecode file format reading prims -*- C++ -*-===// + // + // 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 header defines some basic functions for reading basic primitive types + // from a bytecode stream. + // + //===----------------------------------------------------------------------===// + + #ifndef READERPRIMITIVES_H + #define READERPRIMITIVES_H + + #include "Support/DataTypes.h" + #include + + namespace llvm { + + static inline unsigned read(const unsigned char *&Buf, + const unsigned char *EndBuf) { + if (Buf+4 > EndBuf) throw std::string("Ran out of data!"); + Buf += 4; + return Buf[-4] | (Buf[-3] << 8) | (Buf[-2] << 16) | (Buf[-1] << 24); + } + + + // read_vbr - Read an unsigned integer encoded in variable bitrate format. + // + static inline unsigned read_vbr_uint(const unsigned char *&Buf, + const unsigned char *EndBuf) { + unsigned Shift = 0; + unsigned Result = 0; + + do { + if (Buf == EndBuf) throw std::string("Ran out of data!"); + Result |= (unsigned)((*Buf++) & 0x7F) << Shift; + Shift += 7; + } while (Buf[-1] & 0x80); + return Result; + } + + static inline uint64_t read_vbr_uint64(const unsigned char *&Buf, + const unsigned char *EndBuf) { + unsigned Shift = 0; + uint64_t Result = 0; + + do { + if (Buf == EndBuf) throw std::string("Ran out of data!"); + Result |= (uint64_t)((*Buf++) & 0x7F) << Shift; + Shift += 7; + } while (Buf[-1] & 0x80); + return Result; + } + + static inline int64_t read_vbr_int64(const unsigned char *&Buf, + const unsigned char *EndBuf) { + uint64_t R = read_vbr_uint64(Buf, EndBuf); + if (R & 1) { + if (R != 1) + return -(int64_t)(R >> 1); + else // There is no such thing as -0 with integers. "-0" really means + // 0x8000000000000000. + return 1LL << 63; + } else + return (int64_t)(R >> 1); + } + + // align32 - Round up to multiple of 32 bits... + static inline void align32(const unsigned char *&Buf, + const unsigned char *EndBuf) { + Buf = (const unsigned char *)((unsigned long)(Buf+3) & (~3UL)); + if (Buf > EndBuf) throw std::string("Ran out of data!"); + } + + static inline std::string read_str(const unsigned char *&Buf, + const unsigned char *EndBuf) { + unsigned Size = read_vbr_uint(Buf, EndBuf); + const unsigned char *OldBuf = Buf; + Buf += Size; + if (Buf > EndBuf) // Size invalid? + throw std::string("Ran out of data reading a string!"); + return std::string((char*)OldBuf, Size); + } + + static inline void input_data(const unsigned char *&Buf, + const unsigned char *EndBuf, + void *Ptr, void *End) { + unsigned char *Start = (unsigned char *)Ptr; + unsigned Amount = (unsigned char *)End - Start; + if (Buf+Amount > EndBuf) throw std::string("Ran out of data!"); + std::copy(Buf, Buf+Amount, Start); + Buf += Amount; + } + + } // End llvm namespace + + #endif From llvm at cs.uiuc.edu Mon Jun 7 12:59:25 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Mon Jun 7 12:59:25 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Instruction.h Message-ID: <200406071753.MAA21470@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Instruction.h updated: 1.53 -> 1.54 --- Log message: Commit For New Tool: llvm-abcd (Analysis of ByteCode Dumper). This tool will (eventually) provide statistical analysis of bytecode files as well as the ability to dump them in a low level format (slot numbers not resolved). The purpose of this is to aid in the Type!=Value change of bug 122: http://llvm.cs.uiuc.edu/PR122 . With this initial release, llvm-abcd merely dumps out the bytecode. However, the infrastructure for separating bytecode parsing from handling the parsing events is in place. The style chosen is similar to SAX XML parsing where a handler object is called to handlign the parsing events. This probably isn't useful to anyone but me right now as there is no analysis yet, and the dumper doesn't work on every bytecode file. It will probably be useful by the end of this week. Note that there is some duplication of code from the bytecode reader. This was done to eliminate errors from being introduced in the reader and to minimize the impact to other LLVM developers. At some point, the Analyzer and the Reader will be integrated to use the same infrastructure. Also, sorry for the minor change to Instruction.h but I just couldn't bring myself to write code that depends on Instruction internals. --- Diffs of the changes: (+6 -1) Index: llvm/include/llvm/Instruction.h diff -u llvm/include/llvm/Instruction.h:1.53 llvm/include/llvm/Instruction.h:1.54 --- llvm/include/llvm/Instruction.h:1.53 Wed May 26 16:41:09 2004 +++ llvm/include/llvm/Instruction.h Mon Jun 7 12:53:43 2004 @@ -87,9 +87,14 @@ } static const char* getOpcodeName(unsigned OpCode); + static inline bool isTerminator(unsigned OpCode) { + return OpCode >= TermOpsBegin && OpCode < TermOpsEnd; + } + inline bool isTerminator() const { // Instance of TerminatorInst? - return iType >= TermOpsBegin && iType < TermOpsEnd; + return isTerminator(iType); } + inline bool isBinaryOp() const { return iType >= BinaryOpsBegin && iType < BinaryOpsEnd; } From lattner at cs.uiuc.edu Mon Jun 7 13:15:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Jun 7 13:15:02 2004 Subject: [llvm-commits] CVS: llvm/tools/llvm-dis/llvm-dis.cpp Message-ID: <200406071810.NAA21764@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-dis: llvm-dis.cpp updated: 1.43 -> 1.44 --- Log message: Eliminate more traces of the -c option --- Diffs of the changes: (+3 -14) Index: llvm/tools/llvm-dis/llvm-dis.cpp diff -u llvm/tools/llvm-dis/llvm-dis.cpp:1.43 llvm/tools/llvm-dis/llvm-dis.cpp:1.44 --- llvm/tools/llvm-dis/llvm-dis.cpp:1.43 Thu May 27 00:38:45 2004 +++ llvm/tools/llvm-dis/llvm-dis.cpp Mon Jun 7 13:10:01 2004 @@ -13,7 +13,6 @@ // to the x.ll file. // Options: // --help - Output information about command line switches -// -c - Print C code instead of LLVM assembly // //===----------------------------------------------------------------------===// @@ -26,12 +25,6 @@ #include #include -// OutputMode - The different orderings to print basic blocks in... -enum OutputMode { - LLVM = 0, // Generate LLVM assembly (the default) - c, // Generate C code -}; - using namespace llvm; static cl::opt @@ -44,12 +37,8 @@ static cl::opt Force("f", cl::desc("Overwrite output files")); -static cl::opt -WriteMode(cl::desc("Specify the output format:"), - cl::values(clEnumValN(LLVM, "llvm", "Output LLVM assembly"), - clEnumVal(c, "Output C code for program"), - 0), - cl::ReallyHidden); +static cl::opt +CWriteMode("c", cl::desc("Obsolete option, do not use"), cl::ReallyHidden); int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, " llvm .bc -> .ll disassembler\n"); @@ -58,7 +47,7 @@ std::ostream *Out = &std::cout; // Default to printing to stdout... std::string ErrorMessage; - if (WriteMode == c) { + if (CWriteMode) { std::cerr << "ERROR: llvm-dis no longer contains the C backend. " << "Use 'llc -march=c' instead!\n"; exit(1); From lattner at cs.uiuc.edu Mon Jun 7 14:40:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Jun 7 14:40:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Support/Timer.cpp Message-ID: <200406071935.OAA06120@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: Timer.cpp updated: 1.29 -> 1.30 --- Log message: Implement getTimeRecord natively in Win32, properly conditionalize the getrusage implementation on HAVE_GETRUSAGE --- Diffs of the changes: (+28 -7) Index: llvm/lib/Support/Timer.cpp diff -u llvm/lib/Support/Timer.cpp:1.29 llvm/lib/Support/Timer.cpp:1.30 --- llvm/lib/Support/Timer.cpp:1.29 Sun Dec 14 15:27:33 2003 +++ llvm/lib/Support/Timer.cpp Mon Jun 7 14:34:51 2004 @@ -13,18 +13,19 @@ #include "Support/Timer.h" #include "Support/CommandLine.h" -#include "Config/sys/resource.h" -#include "Config/sys/time.h" -#include "Config/unistd.h" -#include "Config/malloc.h" -#include #include +#include #include #include #include +#include "Config/sys/resource.h" +#include "Config/sys/time.h" +#include "Config/unistd.h" +#include "Config/malloc.h" +#include "Config/windows.h" using namespace llvm; -// GetLibSupportInfoOutputFile - Return a file stream to print our output on... +// GetLibSupportInfoOutputFile - Return a file stream to print our output on. namespace llvm { extern std::ostream *GetLibSupportInfoOutputFile(); } // getLibSupportInfoOutputFilename - This ugly hack is brought to you courtesy @@ -113,6 +114,23 @@ }; static TimeRecord getTimeRecord(bool Start) { +#if defined(HAVE_WINDOWS_H) + unsigned __int64 ProcCreate, ProcExit, KernelTime, UserTime, CurTime; + + GetProcessTimes(GetCurrentProcess(), (FILETIME*)&ProcCreate, + (FILETIME*)&ProcExit, (FILETIME*)&KernelTime, + (FILETIME*)&UserTime); + GetSystemTimeAsFileTime((FILETIME*)&CurTime); + + // FILETIME's are # of 100 nanosecond ticks. + double ScaleFactor = 1.0/(10*1000*1000); + + TimeRecord Result; + Result.Elapsed = (CurTime-ProcCreate)*ScaleFactor; // Wall time + Result.UserTime = UserTime*ScaleFactor; + Result.SystemTime = KernelTime*ScaleFactor; + return Result; +#elif defined(HAVE_GETRUSAGE) struct rusage RU; struct timeval T; long MemUsed = 0; @@ -134,8 +152,11 @@ Result.UserTime = RU.ru_utime.tv_sec + RU.ru_utime.tv_usec/1000000.0; Result.SystemTime = RU.ru_stime.tv_sec + RU.ru_stime.tv_usec/1000000.0; Result.MemUsed = MemUsed; - return Result; +#else + // Can't get resource usage. + return TimeRecord(); +#endif } static std::vector ActiveTimers; From lattner at cs.uiuc.edu Mon Jun 7 14:42:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Jun 7 14:42:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Support/FileUtilities.cpp Message-ID: <200406071937.OAA06220@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: FileUtilities.cpp updated: 1.23 -> 1.24 --- Log message: Make all of this functionality work directly on win32. Properly conditionalize system specific stuff on HAVE_MKSTEMP --- Diffs of the changes: (+29 -13) Index: llvm/lib/Support/FileUtilities.cpp diff -u llvm/lib/Support/FileUtilities.cpp:1.23 llvm/lib/Support/FileUtilities.cpp:1.24 --- llvm/lib/Support/FileUtilities.cpp:1.23 Sat Jun 5 03:59:43 2004 +++ llvm/lib/Support/FileUtilities.cpp Mon Jun 7 14:37:24 2004 @@ -13,11 +13,13 @@ //===----------------------------------------------------------------------===// #include "Support/FileUtilities.h" +#include "Support/DataTypes.h" #include "Config/unistd.h" #include "Config/fcntl.h" -#include "Config/sys/stat.h" #include "Config/sys/types.h" +#include "Config/sys/stat.h" #include "Config/sys/mman.h" +#include "Config/alloca.h" #include #include #include @@ -28,10 +30,10 @@ /// name a readable file. /// bool llvm::CheckMagic(const std::string &FN, const std::string &Magic) { - char buf[1 + Magic.size ()]; - std::ifstream f (FN.c_str ()); - f.read (buf, Magic.size ()); - buf[Magic.size ()] = '\0'; + char *buf = (char*)alloca(1 + Magic.size()); + std::ifstream f(FN.c_str()); + f.read(buf, Magic.size()); + buf[Magic.size()] = '\0'; return Magic == buf; } @@ -41,7 +43,7 @@ bool llvm::IsArchive(const std::string &FN) { // Inspect the beginning of the file to see if it contains the "ar" // library archive format magic string. - return CheckMagic (FN, "!\012"); + return CheckMagic(FN, "!\012"); } /// IsBytecode - Returns true IFF the file named FN appears to be an LLVM @@ -179,8 +181,11 @@ strcpy(FNBuffer+FilenameBase.size(), "-XXXXXX"); // Agree on a temporary file name to use.... +#if defined(HAVE_MKSTEMP) && !defined(_MSC_VER) int TempFD; if ((TempFD = mkstemp(FNBuffer)) == -1) { + // FIXME: this should return an emtpy string or something and allow the + // caller to deal with the error! std::cerr << "bugpoint: ERROR: Cannot create temporary file in the current " << " directory!\n"; exit(1); @@ -189,22 +194,33 @@ // We don't need to hold the temp file descriptor... we will trust that no one // will overwrite/delete the file while we are working on it... close(TempFD); +#else + // If we don't have mkstemp, use the old and obsolete mktemp function. + if (mktemp(FNBuffer) == 0) { + // FIXME: this should return an emtpy string or something and allow the + // caller to deal with the error! + std::cerr << "bugpoint: ERROR: Cannot create temporary file in the current " + << " directory!\n"; + exit(1); + } +#endif + std::string Result(FNBuffer); delete[] FNBuffer; return Result; } -static bool AddPermissionsBits (const std::string &Filename, mode_t bits) { +static bool AddPermissionsBits (const std::string &Filename, int bits) { // Get the umask value from the operating system. We want to use it // when changing the file's permissions. Since calling umask() sets // the umask and returns its old value, we must call it a second // time to reset it to the user's preference. - mode_t mask = umask (0777); // The arg. to umask is arbitrary... - umask (mask); + int mask = umask(0777); // The arg. to umask is arbitrary. + umask(mask); // Restore the umask. // Get the file's current mode. struct stat st; - if ((stat (Filename.c_str(), &st)) == -1) + if ((stat(Filename.c_str(), &st)) == -1) return false; // Change the file to have whichever permissions bits from 'bits' @@ -259,8 +275,8 @@ /// failure, return null. void *llvm::ReadFileIntoAddressSpace(const std::string &Filename, unsigned &Length) { -#ifdef HAVE_MMAP_FILE - Length = getFileSize(Filename); +#if defined(HAVE_MMAP_FILE) && !defined(_MSC_VER) + Length = (unsigned)getFileSize(Filename); if ((int)Length == -1) return 0; FDHandle FD(open(Filename.c_str(), O_RDONLY)); @@ -287,7 +303,7 @@ /// UnmapFileFromAddressSpace - Remove the specified file from the current /// address space. void llvm::UnmapFileFromAddressSpace(void *Buffer, unsigned Length) { -#ifdef HAVE_MMAP_FILE +#if defined(HAVE_MMAP_FILE) && !defined(_MSC_VER) if (Length) munmap((char*)Buffer, Length); else From lattner at cs.uiuc.edu Mon Jun 7 18:12:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Jun 7 18:12:02 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Assembler/2004-06-07-VerifierBug.llx Message-ID: <200406072307.SAA30648@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Assembler: 2004-06-07-VerifierBug.llx added (r1.1) --- Log message: New testcase for PR361: http://llvm.cs.uiuc.edu/PR361 --- Diffs of the changes: (+11 -0) Index: llvm/test/Regression/Assembler/2004-06-07-VerifierBug.llx diff -c /dev/null llvm/test/Regression/Assembler/2004-06-07-VerifierBug.llx:1.1 *** /dev/null Mon Jun 7 18:07:20 2004 --- llvm/test/Regression/Assembler/2004-06-07-VerifierBug.llx Mon Jun 7 18:07:09 2004 *************** *** 0 **** --- 1,11 ---- + ; RUN: llvm-as < %s > /dev/null + void %t() { + entry: + ret void + + loop: + %tmp.4.i9 = getelementptr int* null, int %tmp.5.i10 + %tmp.5.i10 = load int* %tmp.4.i9 + br label %loop + } + From lattner at cs.uiuc.edu Mon Jun 7 18:12:10 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Jun 7 18:12:10 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Verifier.cpp Message-ID: <200406072307.SAA30658@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Verifier.cpp updated: 1.105 -> 1.106 --- Log message: Fix PR361: http://llvm.cs.uiuc.edu/PR361 . Dominance properties don't hold in unreachable code --- Diffs of the changes: (+2 -1) Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.105 llvm/lib/VMCore/Verifier.cpp:1.106 --- llvm/lib/VMCore/Verifier.cpp:1.105 Sat Jun 5 12:44:48 2004 +++ llvm/lib/VMCore/Verifier.cpp Mon Jun 7 18:07:33 2004 @@ -592,7 +592,8 @@ else if (OpBlock == BB) { // If they are in the same basic block, make sure that the definition // comes before the use. - Assert2(DS->dominates(Op, &I), + Assert2(DS->dominates(Op, &I) || + !DS->dominates(&BB->getParent()->getEntryBlock(), BB), "Instruction does not dominate all uses!", Op, &I); } From llvm at cs.uiuc.edu Tue Jun 8 00:56:02 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Tue Jun 8 00:56:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Analyzer/Parser.h BytecodeHandler.h Message-ID: <200406080551.AAA09144@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Analyzer: Parser.h updated: 1.1 -> 1.2 BytecodeHandler.h (r1.1) removed --- Log message: Merged BytecodeHandler.h into Parser.h since the parser and the handler must always coexist. Cleaned up the documentation on these interfaces significantly. This is in preparation for moving Parser.h to the include directories to make it a public interface. --- Diffs of the changes: (+374 -54) Index: llvm/lib/Bytecode/Analyzer/Parser.h diff -u llvm/lib/Bytecode/Analyzer/Parser.h:1.1 llvm/lib/Bytecode/Analyzer/Parser.h:1.2 --- llvm/lib/Bytecode/Analyzer/Parser.h:1.1 Mon Jun 7 12:53:43 2004 +++ llvm/lib/Bytecode/Analyzer/Parser.h Tue Jun 8 00:51:18 2004 @@ -1,4 +1,4 @@ -//===-- Parser.h - Definitions internal to the reader -----------*- C++ -*-===// +//===-- Parser.h - Abstract Interface To Bytecode Parsing -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,45 +7,142 @@ // //===----------------------------------------------------------------------===// // -// This header file defines the interface to the Bytecode Parser +// This header file defines the interface to the Bytecode Parser and the +// Bytecode Handler interface that it calls. // //===----------------------------------------------------------------------===// #ifndef BYTECODE_PARSER_H #define BYTECODE_PARSER_H -#include "ReaderPrimitives.h" -#include "BytecodeHandler.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/GlobalValue.h" +#include "llvm/Module.h" #include #include #include namespace llvm { -struct LazyFunctionInfo { - const unsigned char *Buf, *EndBuf; - LazyFunctionInfo(const unsigned char *B = 0, const unsigned char *EB = 0) - : Buf(B), EndBuf(EB) {} -}; - -typedef std::map LazyFunctionMap; +class BytecodeHandler; ///< Forward declare the handler interface +/// This class defines the interface for parsing a buffer of bytecode. The +/// parser itself takes no action except to call the various functions of +/// the handler interface. The parser's sole responsibility is the correct +/// interpretation of the bytecode buffer. The handler is responsible for +/// instantiating and keeping track of all values. As a convenience, the parser +/// is responsible for materializing types and will pass them through the +/// handler interface as necessary. +/// @see BytecodeHandler +/// @brief Abstract Bytecode Parser interface class AbstractBytecodeParser { - AbstractBytecodeParser(const AbstractBytecodeParser &); // DO NOT IMPLEMENT - void operator=(const AbstractBytecodeParser &); // DO NOT IMPLEMENT + +/// @name Constructors +/// @{ public: AbstractBytecodeParser( BytecodeHandler* h ) { handler = h; } ~AbstractBytecodeParser() { } +/// @} +/// @name Types +/// @{ +public: + /// @brief A convenience type for the buffer pointer + typedef const unsigned char* BufPtr; + + /// @brief The type used for vector of potentially abstract types + typedef std::vector TypeListTy; + + /// @brief + +/// @} +/// @name Methods +/// @{ +public: + + /// @brief Main interface to parsing a bytecode buffer. void ParseBytecode(const unsigned char *Buf, unsigned Length, const std::string &ModuleID); - void dump() const { - std::cerr << "AbstractBytecodeParser instance!\n"; - } + /// The ParseBytecode method lazily parses functions. Use this + /// method to cause the parser to actually parse all the function bodies + /// in the bytecode buffer. + /// @see ParseBytecode + /// @brief Parse all function bodies + void ParseAllFunctionBodies (); + + /// The Parsebytecode method lazily parses functions. Use this + /// method to casue the parser to parse the next function of a given + /// types. Note that this will remove the function from what is to be + /// included by ParseAllFunctionBodies. + /// @see ParseAllFunctionBodies + /// @see ParseBytecode + /// @brief Parse the next function of specific type + void ParseNextFunction (Type* FType) ; + +/// @} +/// @name Parsing Units For Subclasses +/// @{ +protected: + /// @brief Parse whole module scope + void ParseModule (BufPtr &Buf, BufPtr End); + + /// @brief Parse the version information block + void ParseVersionInfo (BufPtr &Buf, BufPtr End); + + /// @brief Parse the ModuleGlobalInfo block + void ParseModuleGlobalInfo (BufPtr &Buf, BufPtr End); + + /// @brief Parse a symbol table + void ParseSymbolTable (BufPtr &Buf, BufPtr End); + + /// This function parses LLVM functions lazily. It obtains the type of the + /// function and records where the body of the function is in the bytecode + /// buffer. The caller can then use the ParseNextFunction and + /// ParseAllFunctionBodies to get handler events for the functions. + /// @brief Parse functions lazily. + void ParseFunctionLazily (BufPtr &Buf, BufPtr End); + + /// @brief Parse a function body + void ParseFunctionBody (const Type* FType, BufPtr &Buf, BufPtr EndBuf); + + /// @brief Parse a compaction table + void ParseCompactionTable (BufPtr &Buf, BufPtr End); + + /// @brief Parse global types + void ParseGlobalTypes (BufPtr &Buf, BufPtr End); + + /// @brief Parse a basic block (for LLVM 1.0 basic block blocks) + void ParseBasicBlock (BufPtr &Buf, BufPtr End, unsigned BlockNo); + + /// @brief parse an instruction list (for post LLVM 1.0 instruction lists + /// with blocks differentiated by terminating instructions. + unsigned ParseInstructionList(BufPtr &Buf, BufPtr End); + + /// @brief Parse an instruction. + bool ParseInstruction (BufPtr &Buf, BufPtr End, + std::vector& Args); + + /// @brief Parse a constant pool + void ParseConstantPool (BufPtr &Buf, BufPtr End, TypeListTy& List); + + /// @brief Parse a constant value + void ParseConstantValue (BufPtr &Buf, BufPtr End, unsigned TypeID); + + /// @brief Parse a block of types. + void ParseTypeConstants (BufPtr &Buf, BufPtr End, TypeListTy &Tab, + unsigned NumEntries); + /// @brief Parse a single type. + const Type *ParseTypeConstant(BufPtr &Buf, BufPtr End); + + /// @brief Parse a string constants block + void ParseStringConstants (BufPtr &Buf, BufPtr End, unsigned NumEntries); + +/// @} +/// @name Data +/// @{ private: // Information about the module, extracted from the bytecode revision number. unsigned char RevisionNum; // The rev # itself @@ -82,13 +179,13 @@ // TypesLoaded - This vector mirrors the Values[TypeTyID] plane. It is used // to deal with forward references to types. // - typedef std::vector TypeListTy; TypeListTy ModuleTypes; TypeListTy FunctionTypes; // When the ModuleGlobalInfo section is read, we create a FunctionType object // for each function in the module. When the function is loaded, this type is // used to instantiate the actual function object. + std::vector FunctionSignatureList; // Constant values are read in after global variables. Because of this, we @@ -98,16 +195,34 @@ // std::vector > GlobalInits; - // For lazy reading-in of functions, we need to save away several pieces of - // information about each function: its begin and end pointer in the buffer - // and its FunctionSlot. - // - LazyFunctionMap LazyFunctionLoadMap; - - /// The handler for parsing +/// @} +/// @name Implementation Details +/// @{ +private: + /// This stores the parser's handler. It makes virtual function calls through + /// the BytecodeHandler to notify the handler of parsing events. What the + /// handler does with the events is completely orthogonal to the business of + /// parsing the bytecode. + /// @brief The handler of bytecode parsing events. BytecodeHandler* handler; + /// For lazy reading-in of functions, we need to save away several pieces of + /// information about each function: its begin and end pointer in the buffer + /// and its FunctionSlot. + struct LazyFunctionInfo { + const unsigned char *Buf, *EndBuf; + LazyFunctionInfo(const unsigned char *B = 0, const unsigned char *EB = 0) + : Buf(B), EndBuf(EB) {} + }; + typedef std::map LazyFunctionMap; + LazyFunctionMap LazyFunctionLoadMap; + private: + + static inline void readBlock(const unsigned char *&Buf, + const unsigned char *EndBuf, + unsigned &Type, unsigned &Size) ; + const Type *AbstractBytecodeParser::getType(unsigned ID); /// getGlobalTableType - This is just like getType, but when a compaction /// table is in use, it is ignored. Also, no forward references or other @@ -134,45 +249,250 @@ return Type::FirstDerivedTyID + (&*I - &ModuleTypes[0]); } + AbstractBytecodeParser(const AbstractBytecodeParser &); // DO NOT IMPLEMENT + void operator=(const AbstractBytecodeParser &); // DO NOT IMPLEMENT + +/// @} +}; + +/// This class provides the interface for the handling bytecode events during +/// parsing. The methods on this interface are invoked by the +/// AbstractBytecodeParser as it discovers the content of a bytecode stream. +/// This class provides a a clear separation of concerns between recognizing +/// the semantic units of a bytecode file and deciding what to do with them. +/// The AbstractBytecodeParser recognizes the content of the bytecode file and +/// calls the BytecodeHandler methods to determine what should be done. This +/// arrangement allows Bytecode files to be read and handled for a number of +/// purposes simply by creating a subclass of BytecodeHandler. None of the +/// parsing details need to be understood, only the meaning of the calls +/// made on this interface. +/// +/// Another paradigm that uses this design pattern is the XML SAX Parser. The +/// ContentHandler for SAX plays the same role as the BytecodeHandler here. +/// @see AbstractbytecodeParser +/// @brief Handle Bytecode Parsing Events +class BytecodeHandler { + +/// @name Constructors And Operators +/// @{ public: - typedef const unsigned char* BufPtr; - void ParseModule (BufPtr &Buf, BufPtr End); - void ParseNextFunction (Type* FType) ; - void ParseAllFunctionBodies (); + /// @brief Default constructor (empty) + BytecodeHandler() {} + /// @brief Virtual destructor (empty) + virtual ~BytecodeHandler() {} private: - void ParseVersionInfo (BufPtr &Buf, BufPtr End); - void ParseModuleGlobalInfo (BufPtr &Buf, BufPtr End); - void ParseSymbolTable (BufPtr &Buf, BufPtr End); - void ParseFunctionLazily (BufPtr &Buf, BufPtr End); - void ParseFunctionBody (const Type* FType, BufPtr &Buf, BufPtr EndBuf); - void ParseCompactionTable (BufPtr &Buf, BufPtr End); - void ParseGlobalTypes (BufPtr &Buf, BufPtr End); + BytecodeHandler(const BytecodeHandler &); // DO NOT IMPLEMENT + void operator=(const BytecodeHandler &); // DO NOT IMPLEMENT - void ParseBasicBlock (BufPtr &Buf, BufPtr End, unsigned BlockNo); - unsigned ParseInstructionList(BufPtr &Buf, BufPtr End); - - bool ParseInstruction (BufPtr &Buf, BufPtr End, - std::vector& Args); +/// @} +/// @name Handler Methods +/// @{ +public: - void ParseConstantPool (BufPtr &Buf, BufPtr End, TypeListTy& List); - void ParseConstantValue (BufPtr &Buf, BufPtr End, unsigned TypeID); - void ParseTypeConstants (BufPtr &Buf, BufPtr End, TypeListTy &Tab, - unsigned NumEntries); - const Type *ParseTypeConstant(BufPtr &Buf, BufPtr End); - void ParseStringConstants (BufPtr &Buf, BufPtr End, unsigned NumEntries); + /// This method is called whenever the parser detects an error in the + /// bytecode formatting. Returning true will cause the parser to keep + /// going, however this is inadvisable in most cases. Returning false will + /// cause the parser to throw the message as a std::string. + /// @brief Handle parsing errors. + virtual bool handleError(const std::string& str ); + + /// This method is called at the beginning of a parse before anything is + /// read in order to give the handler a chance to initialize. + /// @brief Handle the start of a bytecode parse + virtual void handleStart(); + + /// This method is called at the end of a parse after everything has been + /// read in order to give the handler a chance to terminate. + /// @brief Handle the end of a bytecode parse + virtual void handleFinish(); + + /// This method is called at the start of a module to indicate that a + /// module is being parsed. + /// @brief Handle the start of a module. + virtual void handleModuleBegin(const std::string& id); + + /// This method is called at the end of a module to indicate that the module + /// previously being parsed has concluded. + /// @brief Handle the end of a module. + virtual void handleModuleEnd(const std::string& id); + + /// This method is called once the version information has been parsed. It + /// provides the information about the version of the bytecode file being + /// read. + /// @brief Handle the bytecode prolog + virtual void handleVersionInfo( + unsigned char RevisionNum, ///< Byte code revision number + Module::Endianness Endianness, ///< Endianness indicator + Module::PointerSize PointerSize ///< PointerSize indicator + ); + + /// This method is called at the start of a module globals block which + /// contains the global variables and the function placeholders + virtual void handleModuleGlobalsBegin(); + + /// This method is called when a non-initialized global variable is + /// recognized. Its type, constness, and linkage type are provided. + /// @brief Handle a non-initialized global variable + virtual void handleGlobalVariable( + const Type* ElemType, ///< The type of the global variable + bool isConstant, ///< Whether the GV is constant or not + GlobalValue::LinkageTypes ///< The linkage type of the GV + ); + + /// This method is called when an initialized global variable is recognized. + /// Its type constness, linkage type, and the slot number of the initializer + /// are provided. + /// @brief Handle an intialized global variable. + virtual void handleInitializedGV( + const Type* ElemType, ///< The type of the global variable + bool isConstant, ///< Whether the GV is constant or not + GlobalValue::LinkageTypes,///< The linkage type of the GV + unsigned initSlot ///< Slot number of GV's initializer + ); + + /// This method is called when a new type is recognized. The type is + /// converted from the bytecode and passed to this method. + /// @brief Handle a type + virtual void handleType( const Type* Ty ); + + /// This method is called when the function prototype for a function is + /// encountered in the module globals block. + virtual void handleFunctionDeclaration( + const Type* FuncType ///< The type of the function + ); + + /// This method is called at the end of the module globals block. + /// @brief Handle end of module globals block. + virtual void handleModuleGlobalsEnd(); + + /// This method is called at the beginning of a compaction table. + /// @brief Handle start of compaction table. + virtual void handleCompactionTableBegin(); + + /// @brief Handle start of a compaction table plane + virtual void handleCompactionTablePlane( + unsigned Ty, + unsigned NumEntries + ); + + + /// @brief Handle a type entry in the compaction table + virtual void handleCompactionTableType( + unsigned i, + unsigned TypSlot, + const Type* + ); + + /// @brief Handle a value entry in the compaction table + virtual void handleCompactionTableValue( + unsigned i, + unsigned ValSlot, + const Type* + ); + + /// @brief Handle end of a compaction table + virtual void handleCompactionTableEnd(); + + /// @brief Handle start of a symbol table + virtual void handleSymbolTableBegin(); + + /// @brief Handle start of a symbol table plane + virtual void handleSymbolTablePlane( + unsigned Ty, + unsigned NumEntries, + const Type* Ty + ); + + /// @brief Handle a named type in the symbol table + virtual void handleSymbolTableType( + unsigned i, + unsigned slot, + const std::string& name + ); + + /// @brief Handle a named value in the symbol table + virtual void handleSymbolTableValue( + unsigned i, + unsigned slot, + const std::string& name + ); + + /// @brief Handle the end of a symbol table + virtual void handleSymbolTableEnd(); + + /// @brief Handle the beginning of a function body + virtual void handleFunctionBegin( + const Type* FType, + GlobalValue::LinkageTypes linkage + ); + + /// @brief Handle the end of a function body + virtual void handleFunctionEnd( + const Type* FType + ); + + /// @brief Handle the beginning of a basic block + virtual void handleBasicBlockBegin( + unsigned blocknum + ); + + /// This method is called for each instruction that is parsed. + /// @returns true if the instruction is a block terminating instruction + /// @brief Handle an instruction + virtual bool handleInstruction( + unsigned Opcode, + const Type* iType, + std::vector& Operands + ); + + /// @brief Handle the end of a basic block + virtual void handleBasicBlockEnd(unsigned blocknum); + + /// @brief Handle start of global constants block. + virtual void handleGlobalConstantsBegin(); + + /// @brief Handle a constant expression + virtual void handleConstantExpression( + unsigned Opcode, + const Type* Typ, + std::vector > ArgVec + ); + + /// @brief Handle a constant array + virtual void handleConstantArray( + const ArrayType* AT, + std::vector& ElementSlots + ); + + /// @brief Handle a constant structure + virtual void handleConstantStruct( + const StructType* ST, + std::vector& ElementSlots + ); + + /// @brief Handle a constant pointer + virtual void handleConstantPointer( + const PointerType* PT, + unsigned Slot + ); + + /// @brief Handle a constant strings (array special case) + virtual void handleConstantString( + const ConstantArray* CA + ); -}; + /// @brief Handle a primitive constant value + virtual void handleConstantValue( Constant * c ); + + /// @brief Handle the end of the global constants + virtual void handleGlobalConstantsEnd(); +/// @} -static inline void readBlock(const unsigned char *&Buf, - const unsigned char *EndBuf, - unsigned &Type, unsigned &Size) { - Type = read(Buf, EndBuf); - Size = read(Buf, EndBuf); -} +}; } // End llvm namespace -#endif // vim: sw=2 +#endif From llvm at cs.uiuc.edu Tue Jun 8 00:58:01 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Tue Jun 8 00:58:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Analyzer/AnalyzerInternals.h Message-ID: <200406080552.AAA09166@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Analyzer: AnalyzerInternals.h updated: 1.1 -> 1.2 --- Log message: Adjust what's included to compensate for changes in Parser.h --- Diffs of the changes: (+11 -0) Index: llvm/lib/Bytecode/Analyzer/AnalyzerInternals.h diff -u llvm/lib/Bytecode/Analyzer/AnalyzerInternals.h:1.1 llvm/lib/Bytecode/Analyzer/AnalyzerInternals.h:1.2 --- llvm/lib/Bytecode/Analyzer/AnalyzerInternals.h:1.1 Mon Jun 7 12:53:43 2004 +++ llvm/lib/Bytecode/Analyzer/AnalyzerInternals.h Tue Jun 8 00:52:29 2004 @@ -14,8 +14,11 @@ #ifndef ANALYZER_INTERNALS_H #define ANALYZER_INTERNALS_H +#include "ReaderPrimitives.h" #include "Parser.h" #include "llvm/Bytecode/Analyzer.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" // Enable to trace to figure out what the heck is going on when parsing fails //#define TRACE_LEVEL 10 @@ -29,6 +32,14 @@ #endif namespace llvm { + +inline void AbstractBytecodeParser::readBlock(const unsigned char *&Buf, + const unsigned char *EndBuf, + unsigned &Type, unsigned &Size) +{ + Type = read(Buf, EndBuf); + Size = read(Buf, EndBuf); +} class BytecodeAnalyzer { BytecodeAnalyzer(const BytecodeAnalyzer &); // DO NOT IMPLEMENT From llvm at cs.uiuc.edu Tue Jun 8 00:58:06 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Tue Jun 8 00:58:06 2004 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Analyzer/BytecodeHandler.cpp Message-ID: <200406080553.AAA09189@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Analyzer: BytecodeHandler.cpp updated: 1.1 -> 1.2 --- Log message: Make it #include Parser.h instead of AnalyzerInternals.h since it only needs the BytecodeHandler interface which is now in Parser.h --- Diffs of the changes: (+1 -1) Index: llvm/lib/Bytecode/Analyzer/BytecodeHandler.cpp diff -u llvm/lib/Bytecode/Analyzer/BytecodeHandler.cpp:1.1 llvm/lib/Bytecode/Analyzer/BytecodeHandler.cpp:1.2 --- llvm/lib/Bytecode/Analyzer/BytecodeHandler.cpp:1.1 Mon Jun 7 12:53:43 2004 +++ llvm/lib/Bytecode/Analyzer/BytecodeHandler.cpp Tue Jun 8 00:53:14 2004 @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "BytecodeHandler.h" +#include "Parser.h" using namespace llvm; From llvm at cs.uiuc.edu Tue Jun 8 01:00:05 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Tue Jun 8 01:00:05 2004 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Analyzer/Parser.cpp Message-ID: <200406080554.AAA09209@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Analyzer: Parser.cpp updated: 1.1 -> 1.2 --- Log message: Fix the bug that was preventing the parser from working on all bytecode files. It was reading non-initialized global vars when the flag said it was initialized and vice versa. Causes mis-alignment since initialized and non-initialized constants have different bytecode lengths. --- Diffs of the changes: (+5 -5) Index: llvm/lib/Bytecode/Analyzer/Parser.cpp diff -u llvm/lib/Bytecode/Analyzer/Parser.cpp:1.1 llvm/lib/Bytecode/Analyzer/Parser.cpp:1.2 --- llvm/lib/Bytecode/Analyzer/Parser.cpp:1.1 Mon Jun 7 12:53:43 2004 +++ llvm/lib/Bytecode/Analyzer/Parser.cpp Tue Jun 8 00:54:47 2004 @@ -156,7 +156,8 @@ /// ParseInstructionList - Parse all of the BasicBlock's & Instruction's in the /// body of a function. In post 1.0 bytecode files, we no longer emit basic /// block individually, in order to avoid per-basic-block overhead. -unsigned AbstractBytecodeParser::ParseInstructionList( BufPtr &Buf, BufPtr EndBuf) { +unsigned AbstractBytecodeParser::ParseInstructionList( BufPtr &Buf, + BufPtr EndBuf) { unsigned BlockNo = 0; std::vector Args; @@ -698,12 +699,11 @@ const Type *ElTy = cast(Ty)->getElementType(); // Create the global variable... - if (hasInitializer) - handler->handleGlobalVariable( ElTy, isConstant, Linkage ); - else { + if (hasInitializer) { unsigned initSlot = read_vbr_uint(Buf,End); handler->handleInitializedGV( ElTy, isConstant, Linkage, initSlot ); - } + } else + handler->handleGlobalVariable( ElTy, isConstant, Linkage ); // Get next item VarType = read_vbr_uint(Buf, End); From llvm at cs.uiuc.edu Tue Jun 8 01:01:02 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Tue Jun 8 01:01:02 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Bytecode/Analyzer.h Message-ID: <200406080556.AAA09238@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Bytecode: Analyzer.h updated: 1.1 -> 1.2 --- Log message: Clean up documentation and make it possible for the BytecodeAnalyzer to store the output of the bytecode dumper. --- Diffs of the changes: (+17 -6) Index: llvm/include/llvm/Bytecode/Analyzer.h diff -u llvm/include/llvm/Bytecode/Analyzer.h:1.1 llvm/include/llvm/Bytecode/Analyzer.h:1.2 --- llvm/include/llvm/Bytecode/Analyzer.h:1.1 Mon Jun 7 12:53:43 2004 +++ llvm/include/llvm/Bytecode/Analyzer.h Tue Jun 8 00:55:53 2004 @@ -1,4 +1,4 @@ -//===-- llvm/Bytecode/Analyzer.h - Analyzer for bytecode files --*- C++ -*-===// +//===-- llvm/Bytecode/Analyzer.h - Analyzer for Bytecode files --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -8,10 +8,11 @@ //===----------------------------------------------------------------------===// // // This functionality is implemented by the lib/Bytecode/Analysis library. -// This library is used to read VM bytecode files from an iostream and print -// out a diagnostic analysis of the contents of the file. It is intended for -// three uses: (a) understanding the bytecode format, (b) ensuring correctness -// of bytecode format, (c) statistical analysis of generated bytecode files. +// This library is used to read VM bytecode files from a file or memory buffer +// and print out a diagnostic analysis of the contents of the file. It is +// intended for three uses: (a) understanding the bytecode format, (b) ensuring +// correctness of bytecode format, (c) statistical analysis of generated +// bytecode files. // //===----------------------------------------------------------------------===// @@ -61,8 +62,12 @@ /// function. std::map FunctionInfo; + /// The content of the bytecode dump + std::string BytecodeDump; + /// Flags for what should be done - bool dumpBytecode; + bool dumpBytecode; ///< If true, BytecodeDump has contents + bool detailedResults; ///< If true, FunctionInfo has contents }; /// This function is the main entry point into the bytecode analysis library. It @@ -91,6 +96,12 @@ /// a human legible form. /// @brief Print BytecodeAnalysis structure to an ostream void PrintBytecodeAnalysis(BytecodeAnalysis& bca, std::ostream& Out ); + +/// @brief std::ostream inserter for BytecodeAnalysis structure +inline std::ostream& operator<<(std::ostream& Out, BytecodeAnalysis& bca ) { + PrintBytecodeAnalysis(bca,Out); + return Out; +} } // End llvm namespace From llvm at cs.uiuc.edu Tue Jun 8 01:02:01 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Tue Jun 8 01:02:01 2004 Subject: [llvm-commits] CVS: llvm/tools/llvm-abcd/llvm-abcd.cpp Message-ID: <200406080557.AAA09258@zion.cs.uiuc.edu> Changes in directory llvm/tools/llvm-abcd: llvm-abcd.cpp updated: 1.1 -> 1.2 --- Log message: Clean up the documentation. Simplify the file handling. It now only writes to std::cout. --- Diffs of the changes: (+24 -60) Index: llvm/tools/llvm-abcd/llvm-abcd.cpp diff -u llvm/tools/llvm-abcd/llvm-abcd.cpp:1.1 llvm/tools/llvm-abcd/llvm-abcd.cpp:1.2 --- llvm/tools/llvm-abcd/llvm-abcd.cpp:1.1 Mon Jun 7 12:53:43 2004 +++ llvm/tools/llvm-abcd/llvm-abcd.cpp Tue Jun 8 00:56:58 2004 @@ -1,20 +1,29 @@ -//===-- llvm-dis.cpp - The low-level LLVM disassembler --------------------===// +//===-- llvm-abcd.cpp - Analysis of Byte Code Dumper ----------------------===// // // 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 was developed by Reid Spencerearch and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // -// This utility may be invoked in the following manner: -// llvm-dis [options] - Read LLVM bytecode from stdin, write asm to stdout -// llvm-dis [options] x.bc - Read LLVM bytecode from the x.bc file, write asm -// to the x.ll file. +// This tool may be invoked in the following manner: +// llvm-abcd [options] - Read LLVM bytecode from stdin +// llvm-abcd [options] x.bc - Read LLVM bytecode from the x.bc file +// // Options: -// --help - Output information about command line switches -// -c - Print C code instead of LLVM assembly +// --help - Output information about command line switches +// --details - Provide detailed analysis of individual functions +// --dump - Dump bytecode in readable format // +// This tool provides analytical information about a bytecode file. It is +// intended as an aid to developers of bytecode reading and writing software. It +// produces on std::out a summary of the bytecode file that shows various +// statistics about the contents of the file. If the -details option is given +// then the output includes detailed information about each function in the +// bytecode file. The tool is also able to print a bytecode file in a straight +// forward text format // that shows the containment and relationships of the +// information in the bytecode file (-dump option). //===----------------------------------------------------------------------===// #include "llvm/Bytecode/Analyzer.h" @@ -28,12 +37,8 @@ static cl::opt InputFilename(cl::Positional, cl::desc(""), cl::init("-")); -static cl::opt - OutputFilename("o", cl::desc("Override output filename"), - cl::value_desc("filename")); - -static cl::opt Force ("f", cl::desc("Overwrite output files")); -static cl::opt Detailed ("d", cl::desc("Detailed output")); +static cl::opt Detailed ("details", cl::desc("Detailed output")); +static cl::opt Dump ("dump", cl::desc("Detailed output")); int main(int argc, char **argv) @@ -48,6 +53,10 @@ std::string ErrorMessage; BytecodeAnalysis bca; + /// Determine what to generate + bca.dumpBytecode = Dump; + bca.detailedResults = Detailed; + /// Analyze the bytecode file AnalyzeBytecodeFile(InputFilename, bca, &ErrorMessage); @@ -57,52 +66,7 @@ return 1; } - // Figure out where the output is going - if (OutputFilename != "") { // Specified an output filename? - if (OutputFilename != "-") { // Not stdout? - if (!Force && std::ifstream(OutputFilename.c_str())) { - // If force is not specified, make sure not to overwrite a file! - std::cerr << argv[0] << ": error opening '" << OutputFilename - << "': file exists! Sending to standard output.\n"; - } else { - Out = new std::ofstream(OutputFilename.c_str()); - } - } - } else { - if (InputFilename == "-") { - OutputFilename = "-"; - } else { - std::string IFN = InputFilename; - int Len = IFN.length(); - if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') { - // Source ends in .bc - OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".abc"; - } else { - OutputFilename = IFN+".abc"; - } - - if (!Force && std::ifstream(OutputFilename.c_str())) { - // If force is not specified, make sure not to overwrite a file! - std::cerr << argv[0] << ": error opening '" << OutputFilename - << "': file exists! Sending to standard output.\n"; - } else { - Out = new std::ofstream(OutputFilename.c_str()); - - // Make sure that the Out file gets unlinked from the disk if we get a - // SIGINT - RemoveFileOnSignal(OutputFilename); - } - } - } - - if (!Out->good()) { - std::cerr << argv[0] << ": error opening " << OutputFilename - << ": sending to stdout instead!\n"; - Out = &std::cout; - } - // All that abcd does is write the gathered statistics to the output - bca.dumpBytecode = true; PrintBytecodeAnalysis(bca,*Out); if (Out != &std::cout) { From lattner at cs.uiuc.edu Tue Jun 8 01:28:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 01:28:02 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetFrameInfo.h Message-ID: <200406080623.BAA09366@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetFrameInfo.h updated: 1.11 -> 1.12 --- Log message: Add documentation to the TargetFrameInfo class, contributed by Vladimir Prus --- Diffs of the changes: (+7 -0) Index: llvm/include/llvm/Target/TargetFrameInfo.h diff -u llvm/include/llvm/Target/TargetFrameInfo.h:1.11 llvm/include/llvm/Target/TargetFrameInfo.h:1.12 --- llvm/include/llvm/Target/TargetFrameInfo.h:1.11 Thu Mar 11 17:52:03 2004 +++ llvm/include/llvm/Target/TargetFrameInfo.h Tue Jun 8 01:23:17 2004 @@ -18,6 +18,13 @@ class MachineFunction; +/// Information about stack frame layout on the target. It holds the direction +/// of stack growth, the known stack alignment on entry to each function, and +/// the offset to the locals area. +/// +/// The offset to the local area is the offset from the stack pointer on +/// function entry to the first location where function data (local variables, +/// spill locations) can be stored. struct TargetFrameInfo { enum StackDirection { StackGrowsUp, // Adding to the stack increases the stack address From lattner at cs.uiuc.edu Tue Jun 8 02:15:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 02:15:02 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/CFrontend/2004-06-08-OpaqueStructArg.c Message-ID: <200406080710.CAA15669@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CFrontend: 2004-06-08-OpaqueStructArg.c added (r1.1) --- Log message: Testcase for PR355: http://llvm.cs.uiuc.edu/PR355 --- Diffs of the changes: (+5 -0) Index: llvm/test/Regression/CFrontend/2004-06-08-OpaqueStructArg.c diff -c /dev/null llvm/test/Regression/CFrontend/2004-06-08-OpaqueStructArg.c:1.1 *** /dev/null Tue Jun 8 02:10:21 2004 --- llvm/test/Regression/CFrontend/2004-06-08-OpaqueStructArg.c Tue Jun 8 02:10:11 2004 *************** *** 0 **** --- 1,5 ---- + struct fu; + void foo(struct fu); + void bar() { + foo; + } From lattner at cs.uiuc.edu Tue Jun 8 02:16:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 02:16:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/C++Frontend/2004-06-08-LateTemplateInstantiation.cpp Message-ID: <200406080711.CAA17307@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/C++Frontend: 2004-06-08-LateTemplateInstantiation.cpp added (r1.1) --- Log message: New testcase for PR355: http://llvm.cs.uiuc.edu/PR355 --- Diffs of the changes: (+17 -0) Index: llvm/test/Regression/C++Frontend/2004-06-08-LateTemplateInstantiation.cpp diff -c /dev/null llvm/test/Regression/C++Frontend/2004-06-08-LateTemplateInstantiation.cpp:1.1 *** /dev/null Tue Jun 8 02:11:24 2004 --- llvm/test/Regression/C++Frontend/2004-06-08-LateTemplateInstantiation.cpp Tue Jun 8 02:11:14 2004 *************** *** 0 **** --- 1,17 ---- + + + template + struct normal_iterator { + int FIELD; + }; + + void foo(normal_iterator); + normal_iterator baz(); + + void bar() { + foo(baz()); + } + + void *bar2() { + return (void*)foo; + } From lattner at cs.uiuc.edu Tue Jun 8 02:18:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 02:18:01 2004 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-types.c Message-ID: <200406080712.CAA19469@zion.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-types.c updated: 1.8 -> 1.9 --- Log message: Opaque structure types in function arguments mean that none of the function arguments can be known. Expand the function type as (...), which will allow it to be overloaded later using the normal mechanisms used by the C frontend. This fixes PR355: http://llvm.cs.uiuc.edu/PR355 --- Diffs of the changes: (+11 -2) Index: llvm-gcc/gcc/llvm-types.c diff -u llvm-gcc/gcc/llvm-types.c:1.8 llvm-gcc/gcc/llvm-types.c:1.9 --- llvm-gcc/gcc/llvm-types.c:1.8 Thu Jun 3 01:49:31 2004 +++ llvm-gcc/gcc/llvm-types.c Tue Jun 8 02:12:43 2004 @@ -950,8 +950,17 @@ llvm_type *ArgTy = llvm_type_get_from_tree(TREE_VALUE(Args)); if (isPassedByInvisibleReference(TREE_VALUE(Args))) ArgTy = llvm_type_get_pointer(ArgTy); - assert(ArgTy->ID != OpaqueTyID && "Cannot pass opaque type by value!"); - NumArgs += llvm_type_get_num_recursive_elements(ArgTy); + if (ArgTy->ID != OpaqueTyID) + NumArgs += llvm_type_get_num_recursive_elements(ArgTy); + else { + /* If an opaque struct is being passed by value, we don't know how many + * elements it will expand to. At this point, codegen the prototype as + * (...). + */ + NumArgs = 0; + Args = 0; + break; + } } /* If the function returns a struct, then it REALLY will be From lattner at cs.uiuc.edu Tue Jun 8 02:21:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 02:21:01 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200406080716.CAA20147@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.193 -> 1.194 --- Log message: Bug fixed --- Diffs of the changes: (+2 -1) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.193 llvm/docs/ReleaseNotes.html:1.194 --- llvm/docs/ReleaseNotes.html:1.193 Thu Jun 3 19:40:11 2004 +++ llvm/docs/ReleaseNotes.html Tue Jun 8 02:15:52 2004 @@ -261,6 +261,7 @@ enum type
  • [llvmgcc] Variable length array indexing miscompiled
  • +
  • [llvmgcc] Errors handling function prototypes that take opaque structs by-value
  • @@ -700,7 +701,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/06/04 00:40:11 $ + Last modified: $Date: 2004/06/08 07:15:52 $ From lattner at cs.uiuc.edu Tue Jun 8 02:22:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 02:22:01 2004 Subject: [llvm-commits] CVS: llvm-www/releases/1.2/docs/ReleaseNotes.html Message-ID: <200406080716.CAA20807@zion.cs.uiuc.edu> Changes in directory llvm-www/releases/1.2/docs: ReleaseNotes.html updated: 1.18 -> 1.19 --- Log message: Bug found --- Diffs of the changes: (+2 -2) Index: llvm-www/releases/1.2/docs/ReleaseNotes.html diff -u llvm-www/releases/1.2/docs/ReleaseNotes.html:1.18 llvm-www/releases/1.2/docs/ReleaseNotes.html:1.19 --- llvm-www/releases/1.2/docs/ReleaseNotes.html:1.18 Thu Jun 3 18:43:15 2004 +++ llvm-www/releases/1.2/docs/ReleaseNotes.html Tue Jun 8 02:16:47 2004 @@ -393,7 +393,7 @@
  • [llvmgcc] Crash on use of undeclared enum type
  • [llvmgcc] Variable length array indexing miscompiled
  • - +
  • [llvmgcc] Errors handling function prototypes that take opaque structs by-value
  • @@ -686,7 +686,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/06/03 23:43:15 $ + Last modified: $Date: 2004/06/08 07:16:47 $ From lattner at cs.uiuc.edu Tue Jun 8 02:25:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 02:25:01 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200406080719.CAA21470@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.194 -> 1.195 --- Log message: Ooh, that fixed the annoying warning!! --- Diffs of the changes: (+3 -1) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.194 llvm/docs/ReleaseNotes.html:1.195 --- llvm/docs/ReleaseNotes.html:1.194 Tue Jun 8 02:15:52 2004 +++ llvm/docs/ReleaseNotes.html Tue Jun 8 02:19:29 2004 @@ -158,6 +158,8 @@
  • [llvmgcc] type names are not emitted for structure typedefs
  • All documentation is now conformant to the HTML 4.01 (Strict) level.
  • +
  • The spurious "WARNING: Found global types that are not compatible" warning +produced when linking C++ programs has been fixed.
  • @@ -701,7 +703,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/06/08 07:15:52 $ + Last modified: $Date: 2004/06/08 07:19:29 $ From llvm at cs.uiuc.edu Tue Jun 8 02:36:01 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Tue Jun 8 02:36:01 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200406080730.CAA23064@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.195 -> 1.196 --- Log message: Add a note about llvm-abcd, the Analysis of ByteCode Dumper --- Diffs of the changes: (+10 -3) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.195 llvm/docs/ReleaseNotes.html:1.196 --- llvm/docs/ReleaseNotes.html:1.195 Tue Jun 8 02:19:29 2004 +++ llvm/docs/ReleaseNotes.html Tue Jun 8 02:30:31 2004 @@ -105,8 +105,6 @@
  • LLVM now has new loop unrolling and loop unswitching passes.
  • The induction variable substitution pass performs linear function test replacement and exit value replacement optimizations.
  • -
  • The LLVM Bytecode file format is now - documented.
  • LLVM now has first-class support for Accurate Garbage Collection, enabling the use of aggressive copying and generational collectors.
  • @@ -119,6 +117,15 @@ This includes the JIT compiler.
  • The LLVM code generator is now being documented.
  • +
  • There is a new tool, llvm-abcd, the Analysis of ByteCode Dumper (abcd). +This tool can compute basic statistics and bytecode density statistics on a +module or function basis and also dump out bytecode in a textual format that +is lower level than assembly (values are not resolved from slot numbers). +It should only be of interest to (a) those who are working to improve the +bytecode format and (b) those who really want to understand or document the +details of the bytecode format.
  • +
  • The LLVM Bytecode file format is now + being documented.
  • @@ -703,7 +710,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/06/08 07:19:29 $ + Last modified: $Date: 2004/06/08 07:30:31 $ From lattner at cs.uiuc.edu Tue Jun 8 02:36:06 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 02:36:06 2004 Subject: [llvm-commits] CVS: llvm-gcc/gcc/varasm.c Message-ID: <200406080735.CAA14043@apoc.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: varasm.c updated: 1.3 -> 1.4 --- Log message: assemble_external is not needed by the CFE any more, it just adds stuff that we will get later anyway --- Diffs of the changes: (+1 -6) Index: llvm-gcc/gcc/varasm.c diff -u llvm-gcc/gcc/varasm.c:1.3 llvm-gcc/gcc/varasm.c:1.4 --- llvm-gcc/gcc/varasm.c:1.3 Thu Feb 5 10:05:45 2004 +++ llvm-gcc/gcc/varasm.c Tue Jun 8 02:34:54 2004 @@ -1619,14 +1619,9 @@ void assemble_external (tree decl ATTRIBUTE_UNUSED) { + if (EMIT_LLVM) return; if (DECL_P (decl) && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)) { - if (EMIT_LLVM) { - if (!DECL_LLVM_SET_P(decl)) - llvm_assemble_external(decl); - return; - } - /* Because most platforms do not define ASM_OUTPUT_EXTERNAL, the main body of this code is only rarely exercised. To provide some testing, on all platforms, we make sure that the ASM_OUT_FILE is From llvm at cs.uiuc.edu Tue Jun 8 02:47:02 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Tue Jun 8 02:47:02 2004 Subject: [llvm-commits] CVS: llvm/docs/BytecodeFormat.html Message-ID: <200406080741.CAA28170@zion.cs.uiuc.edu> Changes in directory llvm/docs: BytecodeFormat.html updated: 1.9 -> 1.10 --- Log message: Put in a place holder for describing the differences in bytecode format between LLVM versions. This is just a reminder so I don't forget to document it. --- Diffs of the changes: (+38 -1) Index: llvm/docs/BytecodeFormat.html diff -u llvm/docs/BytecodeFormat.html:1.9 llvm/docs/BytecodeFormat.html:1.10 --- llvm/docs/BytecodeFormat.html:1.9 Sat Jun 5 09:18:02 2004 +++ llvm/docs/BytecodeFormat.html Tue Jun 8 02:41:41 2004 @@ -37,6 +37,13 @@
  • Module Symbol Table
  • +
  • Version Differences +
      +
    1. Version 1.2 Differences From 1.3
    2. +
    3. Version 1.1 Differences From 1.2
    4. +
    5. Version 1.0 Differences From 1.1
    6. +
    +
  • Written by Reid Spencer @@ -502,6 +509,36 @@

    + + + +
    +

    This section describes the differences in the Bytecode Format across LLVM +versions. The versions are listed in reverse order because it assumes the +current version is as documented in the previous sections. Each section here +describes the differences between that version and the one that follows +

    +
    + + +
    +

    TBD: How version 1.2 differs from version 1.3

    +
    + + + +
    +

    TBD: How version 1.1 differs from version 1.2

    +
    + + + +
    +

    TBD: How version 1.0 differs from version 1.1

    +

    @@ -514,7 +551,7 @@ Reid Spencer and Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/06/05 14:18:02 $ + Last modified: $Date: 2004/06/08 07:41:41 $ From llvm at cs.uiuc.edu Tue Jun 8 03:07:01 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Tue Jun 8 03:07:01 2004 Subject: [llvm-commits] CVS: llvm/utils/NightlyTest.pl Message-ID: <200406080801.DAA02740@zion.cs.uiuc.edu> Changes in directory llvm/utils: NightlyTest.pl updated: 1.51 -> 1.52 --- Log message: * Fix indentation of Regression Test Results by making sure the GetQMTestResults function closes all its open tags. * Cause XFAIL results to not be reported at all except in the stats. --- Diffs of the changes: (+10 -4) Index: llvm/utils/NightlyTest.pl diff -u llvm/utils/NightlyTest.pl:1.51 llvm/utils/NightlyTest.pl:1.52 --- llvm/utils/NightlyTest.pl:1.51 Thu Jun 3 19:07:12 2004 +++ llvm/utils/NightlyTest.pl Tue Jun 8 03:01:33 2004 @@ -287,6 +287,7 @@ push(@lines,"

    TEST RESULTS

    1. \n"); my $first_list = 1; my $should_break = 1; + my $nocopy = 0; while ( ) { if ( length($_) > 1 ) { chomp($_); @@ -294,7 +295,10 @@ ! m/^ qmtest.target:/ && ! m/^ local/ && ! m/^gmake:/ ) { - if ( m/: XFAIL/ || m/: XPASS/ || m/: FAIL/ ) { + if ( m/: XFAIL/ ) { + $nocopy = 1; + } elsif ( m/: XPASS/ || m/: FAIL/ ) { + $nocopy = 0; if ( $first_list ) { $first_list = 0; $should_break = 1; @@ -306,13 +310,15 @@ if ( $first_list ) { push(@lines,"PERFECT!"); } push(@lines,"

    STATISTICS

    \n");
     	    $should_break = 0;
    +	    $nocopy = 0;
     	  } elsif ( m/^--- TESTS WITH/ ) {
     	    $should_break = 1;
     	    $first_list = 1;
    +	    $nocopy = 0;
     	    push(@lines,"

    TESTS WITH UNEXPECTED RESULTS

    1. \n"); } elsif ( m/^real / ) { last; - } else { + } elsif (!$nocopy) { if ( $should_break ) { push(@lines,"$_
      \n"); } else { @@ -325,8 +331,8 @@ close SRCHFILE; } my $content = join("", at lines); - return "$content\n"; -} + return "$content
    \n"; +} # Get results of feature tests. my $FeatureTestResults; # String containing the results of the feature tests From brukman at cs.uiuc.edu Tue Jun 8 08:54:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Tue Jun 8 08:54:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Bytecode/Analyzer.h Message-ID: <200406081349.IAA06179@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Bytecode: Analyzer.h updated: 1.2 -> 1.3 --- Log message: Fix case of doxygen directive `\p': it's lowercase. --- Diffs of the changes: (+3 -3) Index: llvm/include/llvm/Bytecode/Analyzer.h diff -u llvm/include/llvm/Bytecode/Analyzer.h:1.2 llvm/include/llvm/Bytecode/Analyzer.h:1.3 --- llvm/include/llvm/Bytecode/Analyzer.h:1.2 Tue Jun 8 00:55:53 2004 +++ llvm/include/llvm/Bytecode/Analyzer.h Tue Jun 8 08:49:17 2004 @@ -71,7 +71,7 @@ }; /// This function is the main entry point into the bytecode analysis library. It -/// allows you to simply provide a \P filename and storage for the \P Results +/// allows you to simply provide a \p filename and storage for the \p Results /// that will be filled in with the analysis results. /// @brief Analyze contents of a bytecode File void AnalyzeBytecodeFile( @@ -82,8 +82,8 @@ /// This function is an alternate entry point into the bytecode analysis /// library. It allows you to provide an arbitrary memory buffer which is -/// assumed to contain a complete bytecode file. The \P Buffer is analyzed and -/// the \P Results are filled in. +/// assumed to contain a complete bytecode file. The \p Buffer is analyzed and +/// the \p Results are filled in. /// @brief Analyze contents of a bytecode buffer. void AnalyzeBytecodeBuffer( const unsigned char* Buffer, ///< Pointer to start of bytecode buffer From lattner at cs.uiuc.edu Tue Jun 8 12:27:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 12:27:01 2004 Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/Benchmarks/Shootout/Makefile ackermann.c ary3.c fib2.c hash.c heapsort.c lists.c matrix.c methcall.c nestedloop.c objinst.c random.c sieve.c strcat.c Message-ID: <200406081721.MAA12502@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/SingleSource/Benchmarks/Shootout: Makefile updated: 1.4 -> 1.5 ackermann.c updated: 1.2 -> 1.3 ary3.c updated: 1.2 -> 1.3 fib2.c updated: 1.1 -> 1.2 hash.c updated: 1.1 -> 1.2 heapsort.c updated: 1.2 -> 1.3 lists.c updated: 1.5 -> 1.6 matrix.c updated: 1.2 -> 1.3 methcall.c updated: 1.1 -> 1.2 nestedloop.c updated: 1.1 -> 1.2 objinst.c updated: 1.2 -> 1.3 random.c updated: 1.3 -> 1.4 sieve.c updated: 1.2 -> 1.3 strcat.c updated: 1.1 -> 1.2 --- Log message: Increase the problem sizes of the shootout benchmarks so that they are less noisy. Patch contributed by Valery Khamenya --- Diffs of the changes: (+26 -27) Index: llvm/test/Programs/SingleSource/Benchmarks/Shootout/Makefile diff -u llvm/test/Programs/SingleSource/Benchmarks/Shootout/Makefile:1.4 llvm/test/Programs/SingleSource/Benchmarks/Shootout/Makefile:1.5 --- llvm/test/Programs/SingleSource/Benchmarks/Shootout/Makefile:1.4 Fri Apr 23 13:09:29 2004 +++ llvm/test/Programs/SingleSource/Benchmarks/Shootout/Makefile Tue Jun 8 12:21:42 2004 @@ -1,5 +1,4 @@ LEVEL = ../../../../.. LDFLAGS += -lm -ENABLE_LLI = 1 include $(LEVEL)/test/Programs/SingleSource/Makefile.singlesrc Index: llvm/test/Programs/SingleSource/Benchmarks/Shootout/ackermann.c diff -u llvm/test/Programs/SingleSource/Benchmarks/Shootout/ackermann.c:1.2 llvm/test/Programs/SingleSource/Benchmarks/Shootout/ackermann.c:1.3 --- llvm/test/Programs/SingleSource/Benchmarks/Shootout/ackermann.c:1.2 Tue Jan 22 09:20:21 2002 +++ llvm/test/Programs/SingleSource/Benchmarks/Shootout/ackermann.c Tue Jun 8 12:21:42 2004 @@ -1,5 +1,5 @@ /* -*- mode: c -*- - * $Id: ackermann.c,v 1.2 2002/01/22 15:20:21 lattner Exp $ + * $Id: ackermann.c,v 1.3 2004/06/08 17:21:42 lattner Exp $ * http://www.bagley.org/~doug/shootout/ */ @@ -15,7 +15,7 @@ int main(int argc, char *argv[]) { - int n = ((argc == 2) ? atoi(argv[1]) : 4); + int n = ((argc == 2) ? atoi(argv[1]) : 12); printf("Ack(3,%d): %d\n", n, Ack(3, n)); return(0); Index: llvm/test/Programs/SingleSource/Benchmarks/Shootout/ary3.c diff -u llvm/test/Programs/SingleSource/Benchmarks/Shootout/ary3.c:1.2 llvm/test/Programs/SingleSource/Benchmarks/Shootout/ary3.c:1.3 --- llvm/test/Programs/SingleSource/Benchmarks/Shootout/ary3.c:1.2 Tue Jul 1 12:24:53 2003 +++ llvm/test/Programs/SingleSource/Benchmarks/Shootout/ary3.c Tue Jun 8 12:21:42 2004 @@ -1,5 +1,5 @@ /* -*- mode: c -*- - * $Id: ary3.c,v 1.2 2003/07/01 17:24:53 brukman Exp $ + * $Id: ary3.c,v 1.3 2004/06/08 17:21:42 lattner Exp $ * http://www.bagley.org/~doug/shootout/ * * this program is modified from: @@ -15,7 +15,7 @@ #include int main(int argc, char *argv[]) { - int n = ((argc == 2) ? atoi(argv[1]) : 1); + int n = ((argc == 2) ? atoi(argv[1]) : 1500000); int i, k, *x, *y; x = (int *) calloc(n, sizeof(int)); Index: llvm/test/Programs/SingleSource/Benchmarks/Shootout/fib2.c diff -u llvm/test/Programs/SingleSource/Benchmarks/Shootout/fib2.c:1.1 llvm/test/Programs/SingleSource/Benchmarks/Shootout/fib2.c:1.2 --- llvm/test/Programs/SingleSource/Benchmarks/Shootout/fib2.c:1.1 Fri Dec 14 10:57:13 2001 +++ llvm/test/Programs/SingleSource/Benchmarks/Shootout/fib2.c Tue Jun 8 12:21:42 2004 @@ -1,5 +1,5 @@ /* -*- mode: c -*- - * $Id: fib2.c,v 1.1 2001/12/14 16:57:13 lattner Exp $ + * $Id: fib2.c,v 1.2 2004/06/08 17:21:42 lattner Exp $ * http://www.bagley.org/~doug/shootout/ */ @@ -16,7 +16,7 @@ int main(int argc, char *argv[]) { - int N = ((argc == 2) ? atoi(argv[1]) : 15); + int N = ((argc == 2) ? atoi(argv[1]) : 43); printf("%ld\n", fib(N)); return(0); } Index: llvm/test/Programs/SingleSource/Benchmarks/Shootout/hash.c diff -u llvm/test/Programs/SingleSource/Benchmarks/Shootout/hash.c:1.1 llvm/test/Programs/SingleSource/Benchmarks/Shootout/hash.c:1.2 --- llvm/test/Programs/SingleSource/Benchmarks/Shootout/hash.c:1.1 Fri Dec 14 10:13:38 2001 +++ llvm/test/Programs/SingleSource/Benchmarks/Shootout/hash.c Tue Jun 8 12:21:42 2004 @@ -1,5 +1,5 @@ /* -*- mode: c -*- - * $Id: hash.c,v 1.1 2001/12/14 16:13:38 lattner Exp $ + * $Id: hash.c,v 1.2 2004/06/08 17:21:42 lattner Exp $ * http://www.bagley.org/~doug/shootout/ */ @@ -9,7 +9,7 @@ #include "simple_hash.h" int main(int argc, char *argv[]) { - int i, c=0, n = ((argc == 2) ? atoi(argv[1]) : 1); + int i, c=0, n = ((argc == 2) ? atoi(argv[1]) : 3500000); char buf[32]; struct ht_ht *ht = ht_create(n); Index: llvm/test/Programs/SingleSource/Benchmarks/Shootout/heapsort.c diff -u llvm/test/Programs/SingleSource/Benchmarks/Shootout/heapsort.c:1.2 llvm/test/Programs/SingleSource/Benchmarks/Shootout/heapsort.c:1.3 --- llvm/test/Programs/SingleSource/Benchmarks/Shootout/heapsort.c:1.2 Wed Oct 15 12:36:36 2003 +++ llvm/test/Programs/SingleSource/Benchmarks/Shootout/heapsort.c Tue Jun 8 12:21:42 2004 @@ -1,5 +1,5 @@ /* -*- mode: c -*- - * $Id: heapsort.c,v 1.2 2003/10/15 17:36:36 gaeke Exp $ + * $Id: heapsort.c,v 1.3 2004/06/08 17:21:42 lattner Exp $ * http://www.bagley.org/~doug/shootout/ */ @@ -56,7 +56,7 @@ int main(int argc, char *argv[]) { - int N = ((argc == 2) ? atoi(argv[1]) : 10); + int N = ((argc == 2) ? atoi(argv[1]) : 8000000); double *ary; int i; Index: llvm/test/Programs/SingleSource/Benchmarks/Shootout/lists.c diff -u llvm/test/Programs/SingleSource/Benchmarks/Shootout/lists.c:1.5 llvm/test/Programs/SingleSource/Benchmarks/Shootout/lists.c:1.6 --- llvm/test/Programs/SingleSource/Benchmarks/Shootout/lists.c:1.5 Thu Jul 10 19:06:29 2003 +++ llvm/test/Programs/SingleSource/Benchmarks/Shootout/lists.c Tue Jun 8 12:21:42 2004 @@ -1,5 +1,5 @@ /* -*- mode: c -*- - * $Id: lists.c,v 1.5 2003/07/11 00:06:29 brukman Exp $ + * $Id: lists.c,v 1.6 2004/06/08 17:21:42 lattner Exp $ * http://www.bagley.org/~doug/shootout/ */ @@ -217,7 +217,7 @@ } int main(int argc, char *argv[]) { - int n = ((argc == 2) ? atoi(argv[1]) : 1); + int n = ((argc == 2) ? atoi(argv[1]) : 3000000); int result = 0; while(n--) result = test_lists(); printf("%d\n", result); Index: llvm/test/Programs/SingleSource/Benchmarks/Shootout/matrix.c diff -u llvm/test/Programs/SingleSource/Benchmarks/Shootout/matrix.c:1.2 llvm/test/Programs/SingleSource/Benchmarks/Shootout/matrix.c:1.3 --- llvm/test/Programs/SingleSource/Benchmarks/Shootout/matrix.c:1.2 Fri Aug 9 15:06:19 2002 +++ llvm/test/Programs/SingleSource/Benchmarks/Shootout/matrix.c Tue Jun 8 12:21:42 2004 @@ -1,5 +1,5 @@ /* -*- mode: c -*- - * $Id: matrix.c,v 1.2 2002/08/09 20:06:19 lattner Exp $ + * $Id: matrix.c,v 1.3 2004/06/08 17:21:42 lattner Exp $ * http://www.bagley.org/~doug/shootout/ */ @@ -48,7 +48,7 @@ } int main(int argc, char *argv[]) { - int i, n = ((argc == 2) ? atoi(argv[1]) : 10); + int i, n = ((argc == 2) ? atoi(argv[1]) : 3000000); int **m1 = mkmatrix(SIZE, SIZE); int **m2 = mkmatrix(SIZE, SIZE); Index: llvm/test/Programs/SingleSource/Benchmarks/Shootout/methcall.c diff -u llvm/test/Programs/SingleSource/Benchmarks/Shootout/methcall.c:1.1 llvm/test/Programs/SingleSource/Benchmarks/Shootout/methcall.c:1.2 --- llvm/test/Programs/SingleSource/Benchmarks/Shootout/methcall.c:1.1 Mon Mar 11 11:29:25 2002 +++ llvm/test/Programs/SingleSource/Benchmarks/Shootout/methcall.c Tue Jun 8 12:21:42 2004 @@ -1,5 +1,5 @@ /* -*- mode: c -*- - * $Id: methcall.c,v 1.1 2002/03/11 17:29:25 lattner Exp $ + * $Id: methcall.c,v 1.2 2004/06/08 17:21:42 lattner Exp $ * http://www.bagley.org/~doug/shootout/ */ @@ -66,7 +66,7 @@ int main(int argc, char *argv[]) { - int i, n = ((argc == 2) ? atoi(argv[1]) : 1); + int i, n = ((argc == 2) ? atoi(argv[1]) : 500000000); Toggle *tog; NthToggle *ntog; char val = true; Index: llvm/test/Programs/SingleSource/Benchmarks/Shootout/nestedloop.c diff -u llvm/test/Programs/SingleSource/Benchmarks/Shootout/nestedloop.c:1.1 llvm/test/Programs/SingleSource/Benchmarks/Shootout/nestedloop.c:1.2 --- llvm/test/Programs/SingleSource/Benchmarks/Shootout/nestedloop.c:1.1 Fri Dec 14 10:13:39 2001 +++ llvm/test/Programs/SingleSource/Benchmarks/Shootout/nestedloop.c Tue Jun 8 12:21:42 2004 @@ -1,5 +1,5 @@ /* -*- mode: c -*- - * $Id: nestedloop.c,v 1.1 2001/12/14 16:13:39 lattner Exp $ + * $Id: nestedloop.c,v 1.2 2004/06/08 17:21:42 lattner Exp $ * http://www.bagley.org/~doug/shootout/ */ @@ -8,7 +8,7 @@ int main(int argc, char *argv[]) { - int n = ((argc == 2) ? atoi(argv[1]) : 4); + int n = ((argc == 2) ? atoi(argv[1]) : 46); int a, b, c, d, e, f, x=0; for (a=0; a Changes in directory llvm/include/llvm: AbstractTypeUser.h updated: 1.19 -> 1.20 Instruction.h updated: 1.54 -> 1.55 Module.h updated: 1.44 -> 1.45 Pass.h updated: 1.43 -> 1.44 Value.h updated: 1.50 -> 1.51 iPHINode.h updated: 1.17 -> 1.18 --- Log message: Apparently a particular vendor compiler uses the struct/class tag to MANGLE symbols with. Therefore, if you do not use struct/class consistently, you can get LINK ERRORS. grr. This fixes the link errors for libsupport and vmcore. -Chris --- Diffs of the changes: (+7 -7) Index: llvm/include/llvm/AbstractTypeUser.h diff -u llvm/include/llvm/AbstractTypeUser.h:1.19 llvm/include/llvm/AbstractTypeUser.h:1.20 --- llvm/include/llvm/AbstractTypeUser.h:1.19 Thu Feb 26 01:24:08 2004 +++ llvm/include/llvm/AbstractTypeUser.h Tue Jun 8 12:44:21 2004 @@ -39,7 +39,7 @@ namespace llvm { -class Type; +struct Type; class DerivedType; class AbstractTypeUser { Index: llvm/include/llvm/Instruction.h diff -u llvm/include/llvm/Instruction.h:1.54 llvm/include/llvm/Instruction.h:1.55 --- llvm/include/llvm/Instruction.h:1.54 Mon Jun 7 12:53:43 2004 +++ llvm/include/llvm/Instruction.h Tue Jun 8 12:44:21 2004 @@ -20,7 +20,7 @@ namespace llvm { -class AssemblyAnnotationWriter; +struct AssemblyAnnotationWriter; template struct ilist_traits; template &getList(Module *M); }; -struct Module { +class Module { +public: typedef iplist GlobalListType; typedef iplist FunctionListType; Index: llvm/include/llvm/Pass.h diff -u llvm/include/llvm/Pass.h:1.43 llvm/include/llvm/Pass.h:1.44 --- llvm/include/llvm/Pass.h:1.43 Thu Apr 1 11:15:42 2004 +++ llvm/include/llvm/Pass.h Tue Jun 8 12:44:21 2004 @@ -38,7 +38,7 @@ namespace llvm { class Value; -class BasicBlock; +struct BasicBlock; class Function; class Module; class AnalysisUsage; Index: llvm/include/llvm/Value.h diff -u llvm/include/llvm/Value.h:1.50 llvm/include/llvm/Value.h:1.51 --- llvm/include/llvm/Value.h:1.50 Thu Feb 26 02:08:38 2004 +++ llvm/include/llvm/Value.h Tue Jun 8 12:44:21 2004 @@ -24,11 +24,10 @@ namespace llvm { -class Type; class Constant; class Argument; class Instruction; -class BasicBlock; +struct BasicBlock; class GlobalValue; class Function; class GlobalVariable; Index: llvm/include/llvm/iPHINode.h diff -u llvm/include/llvm/iPHINode.h:1.17 llvm/include/llvm/iPHINode.h:1.18 --- llvm/include/llvm/iPHINode.h:1.17 Wed May 26 19:15:23 2004 +++ llvm/include/llvm/iPHINode.h Tue Jun 8 12:44:21 2004 @@ -18,7 +18,7 @@ namespace llvm { -class BasicBlock; +struct BasicBlock; //===----------------------------------------------------------------------===// // PHINode Class From lattner at cs.uiuc.edu Tue Jun 8 12:58:04 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 12:58:04 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/ConstantFolding.h Message-ID: <200406081753.MAA14572@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: ConstantFolding.h updated: 1.41 -> 1.42 --- Log message: Fix a link error using VS8.0 --- Diffs of the changes: (+1 -1) Index: llvm/lib/VMCore/ConstantFolding.h diff -u llvm/lib/VMCore/ConstantFolding.h:1.41 llvm/lib/VMCore/ConstantFolding.h:1.42 --- llvm/lib/VMCore/ConstantFolding.h:1.41 Thu Mar 11 23:53:41 2004 +++ llvm/lib/VMCore/ConstantFolding.h Tue Jun 8 12:53:24 2004 @@ -23,7 +23,7 @@ namespace llvm { class Constant; - class Type; + struct Type; // Constant fold various types of instruction... Constant *ConstantFoldCastInstruction(const Constant *V, const Type *DestTy); From gaeke at cs.uiuc.edu Tue Jun 8 13:53:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Jun 8 13:53:01 2004 Subject: [llvm-commits] CVS: llvm/Makefile.rules Message-ID: <200406081852.NAA15982@kain.cs.uiuc.edu> Changes in directory llvm: Makefile.rules updated: 1.185 -> 1.186 --- Log message: Explicitly specify libtool tag "CXX" so that if you setenv CXX to something libtool can't parse, e.g., "/path/to/g++ -some-funny-options", then it will still be able to compile and link. --- Diffs of the changes: (+3 -3) Index: llvm/Makefile.rules diff -u llvm/Makefile.rules:1.185 llvm/Makefile.rules:1.186 --- llvm/Makefile.rules:1.185 Tue Jun 1 14:05:53 2004 +++ llvm/Makefile.rules Tue Jun 8 13:52:45 2004 @@ -302,7 +302,7 @@ # # Compile commands with libtool. # -Compile := $(LIBTOOL) --mode=compile $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(CompileCommonOpts) +Compile := $(LIBTOOL) --tag=CXX --mode=compile $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(CompileCommonOpts) CompileC := $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(CompileCommonOpts) # Compile a cpp file, don't link... @@ -323,7 +323,7 @@ # Link final executable # (Note that we always link with the C++ compiler). # -Link := $(LIBTOOL) --mode=link $(CXX) +Link := $(LIBTOOL) --tag=CXX --mode=link $(CXX) # link both projlib and llvmlib libraries LinkG := $(Link) -g -L$(PROJLIBDEBUGSOURCE) -L$(LLVMLIBDEBUGSOURCE) $(STRIP) @@ -341,7 +341,7 @@ endif # Create one .o file from a bunch of .o files... -Relink := ${LIBTOOL} --mode=link $(CXX) +Relink := ${LIBTOOL} --tag=CXX --mode=link $(CXX) # # Configure where the item being compiled should go. From gaeke at cs.uiuc.edu Tue Jun 8 13:54:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Jun 8 13:54:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp Message-ID: <200406081852.NAA15989@kain.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9/InstrSelection: InstrSelection.cpp updated: 1.78 -> 1.79 --- Log message: Add a TmpInstruction ctor that doesn't take a MCFI. --- Diffs of the changes: (+13 -2) Index: llvm/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp diff -u llvm/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp:1.78 llvm/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp:1.79 --- llvm/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp:1.78 Wed Jun 2 00:54:48 2004 +++ llvm/lib/Target/SparcV9/InstrSelection/InstrSelection.cpp Tue Jun 8 13:52:46 2004 @@ -84,6 +84,17 @@ }; } +TmpInstruction::TmpInstruction(Value *s1, Value *s2, const std::string &name) + : Instruction(s1->getType(), Instruction::UserOp1, name) +{ + Operands.push_back(Use(s1, this)); // s1 must be non-null + if (s2) + Operands.push_back(Use(s2, this)); + + // TmpInstructions should not be garbage checked. + LeakDetector::removeGarbageObject(this); +} + TmpInstruction::TmpInstruction(MachineCodeForInstruction& mcfi, Value *s1, Value *s2, const std::string &name) : Instruction(s1->getType(), Instruction::UserOp1, name) @@ -97,9 +108,9 @@ // TmpInstructions should not be garbage checked. LeakDetector::removeGarbageObject(this); } - + // Constructor that requires the type of the temporary to be specified. -// Both S1 and S2 may be NULL.( +// Both S1 and S2 may be NULL. TmpInstruction::TmpInstruction(MachineCodeForInstruction& mcfi, const Type *Ty, Value *s1, Value* s2, const std::string &name) From gaeke at cs.uiuc.edu Tue Jun 8 13:54:05 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Jun 8 13:54:05 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/InstrSelection.h Message-ID: <200406081852.NAA15996@kain.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: InstrSelection.h updated: 1.32 -> 1.33 --- Log message: Add a TmpInstruction ctor that doesn't take a MCFI. --- Diffs of the changes: (+6 -1) Index: llvm/include/llvm/CodeGen/InstrSelection.h diff -u llvm/include/llvm/CodeGen/InstrSelection.h:1.32 llvm/include/llvm/CodeGen/InstrSelection.h:1.33 --- llvm/include/llvm/CodeGen/InstrSelection.h:1.32 Sun Dec 28 15:22:35 2003 +++ llvm/include/llvm/CodeGen/InstrSelection.h Tue Jun 8 13:52:46 2004 @@ -75,7 +75,12 @@ // s1 must be a valid value. s2 may be NULL. TmpInstruction(MachineCodeForInstruction& mcfi, Value *s1, Value *s2 = 0, const std::string &name = ""); - + + // Constructor that uses the type of S1 as the type of the temporary, + // but does not require a MachineCodeForInstruction. + // s1 must be a valid value. s2 may be NULL. + TmpInstruction(Value *s1, Value *s2 = 0, const std::string &name = ""); + // Constructor that requires the type of the temporary to be specified. // Both S1 and S2 may be NULL. TmpInstruction(MachineCodeForInstruction& mcfi, From gaeke at cs.uiuc.edu Tue Jun 8 13:54:08 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Jun 8 13:54:08 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineBasicBlock.h Message-ID: <200406081852.NAA16003@kain.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineBasicBlock.h updated: 1.34 -> 1.35 --- Log message: Add a forwarding method pop_front() that allows you to delete instructions from the beginning of a MBB. --- Diffs of the changes: (+1 -0) Index: llvm/include/llvm/CodeGen/MachineBasicBlock.h diff -u llvm/include/llvm/CodeGen/MachineBasicBlock.h:1.34 llvm/include/llvm/CodeGen/MachineBasicBlock.h:1.35 --- llvm/include/llvm/CodeGen/MachineBasicBlock.h:1.34 Mon May 24 02:14:33 2004 +++ llvm/include/llvm/CodeGen/MachineBasicBlock.h Tue Jun 8 13:52:47 2004 @@ -146,6 +146,7 @@ /// it returns end() iterator getFirstTerminator(); + void pop_front() { Insts.pop_front(); } void push_back(MachineInstr *MI) { Insts.push_back(MI); } template void insert(iterator I, IT S, IT E) { Insts.insert(I, S, E); } From gaeke at cs.uiuc.edu Tue Jun 8 13:55:00 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Jun 8 13:55:00 2004 Subject: [llvm-commits] CVS: reopt/include/reopt/UnpackTraceFunction.h Message-ID: <200406081854.NAA16060@kain.cs.uiuc.edu> Changes in directory reopt/include/reopt: UnpackTraceFunction.h updated: 1.6 -> 1.7 --- Log message: Add prototypes for new methods. --- Diffs of the changes: (+4 -0) Index: reopt/include/reopt/UnpackTraceFunction.h diff -u reopt/include/reopt/UnpackTraceFunction.h:1.6 reopt/include/reopt/UnpackTraceFunction.h:1.7 --- reopt/include/reopt/UnpackTraceFunction.h:1.6 Mon May 31 00:51:42 2004 +++ reopt/include/reopt/UnpackTraceFunction.h Tue Jun 8 13:53:55 2004 @@ -49,7 +49,11 @@ unsigned stackOffsetForReg (const unsigned R) const; void findRegsToSave (MachineFunction &MF); const MachineInstr *containsReturnInstr (MachineBasicBlock &B); + std::string RegStr (const unsigned R) const; void rewriteProlog (MachineFunction &MF, MachineBasicBlock &MBB); + void copyConstantToRegister (MachineFunction &MF, + Constant *C, unsigned Reg, + std::vector &mvec); void rewriteEpilog (MachineFunction &MF, MachineBasicBlock &MBB); public: From gaeke at cs.uiuc.edu Tue Jun 8 13:55:04 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Jun 8 13:55:04 2004 Subject: [llvm-commits] CVS: reopt/test/run-tests Message-ID: <200406081854.NAA16102@kain.cs.uiuc.edu> Changes in directory reopt/test: run-tests updated: 1.3 -> 1.4 --- Log message: Sort tests and add more test programs. --- Diffs of the changes: (+9 -1) Index: reopt/test/run-tests diff -u reopt/test/run-tests:1.3 reopt/test/run-tests:1.4 --- reopt/test/run-tests:1.3 Fri Jun 4 12:58:26 2004 +++ reopt/test/run-tests Tue Jun 8 13:54:01 2004 @@ -40,12 +40,20 @@ case $benchmk in burg) SUBDIR=MultiSource/Applications/Burg ;; siod) SUBDIR=MultiSource/Applications/siod ;; + + shootout) SUBDIR=SingleSource/Benchmarks/Shootout ;; + ary3) SUBDIR=SingleSource/Reoptimizer/Ary3 ;; sieve) SUBDIR=SingleSource/Reoptimizer/Sieve ;; lists) SUBDIR=SingleSource/Reoptimizer/Lists ;; strcat) SUBDIR=SingleSource/Reoptimizer/Strcat ;; - shootout) SUBDIR=SingleSource/Benchmarks/Shootout ;; mynestedloop) SUBDIR=SingleSource/Reoptimizer/MyNestedLoop ;; + fib2) SUBDIR=SingleSource/Reoptimizer/Fib2 ;; + + mcf) SUBDIR=External/SPEC/CINT2000/181.mcf ;; + art) SUBDIR=External/SPEC/CFP2000/179.art;; + equake) SUBDIR=External/SPEC/CFP2000/183.equake ;; + *) die "Error: Unknown benchmark $arg" ;; esac echo "Starting ${action} on $benchmk" From gaeke at cs.uiuc.edu Tue Jun 8 13:55:07 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Jun 8 13:55:07 2004 Subject: [llvm-commits] CVS: reopt/lib/TraceJIT/TraceJITEmitter.cpp Message-ID: <200406081854.NAA16081@kain.cs.uiuc.edu> Changes in directory reopt/lib/TraceJIT: TraceJITEmitter.cpp updated: 1.1 -> 1.2 --- Log message: Only bother calling GetAddressOfSymbol() on external functions. --- Diffs of the changes: (+1 -1) Index: reopt/lib/TraceJIT/TraceJITEmitter.cpp diff -u reopt/lib/TraceJIT/TraceJITEmitter.cpp:1.1 reopt/lib/TraceJIT/TraceJITEmitter.cpp:1.2 --- reopt/lib/TraceJIT/TraceJITEmitter.cpp:1.1 Wed May 26 16:25:13 2004 +++ reopt/lib/TraceJIT/TraceJITEmitter.cpp Tue Jun 8 13:53:58 2004 @@ -175,7 +175,7 @@ // Try looking up the function to see if it is already compiled, if not return // 0. if (isa(V)) { - if (V->hasName ()) { + if (V->hasExternalLinkage () && V->hasName ()) { uint64_t where = (uint64_t) GetAddressOfSymbol (V->getName ()); if (where) return where; From gaeke at cs.uiuc.edu Tue Jun 8 13:55:11 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Jun 8 13:55:11 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp Message-ID: <200406081854.NAA16067@kain.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: UnpackTraceFunction.cpp updated: 1.80 -> 1.81 --- Log message: Expand head-of-file comment. Prune #includes; add some others we'll need. Add a new RegStr method used to print out registers in a uniform way. Don't erase the entry BB in rewriteProlog; sometimes the code generator puts important stuff there. Instead, just delete the old prolog instrs. Add a new copyConstantToRegister method. Use it to try to deal with live-outs that have been turned into constants in the TraceFn. --- Diffs of the changes: (+90 -45) Index: reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp diff -u reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.80 reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.81 --- reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp:1.80 Fri Jun 4 12:58:24 2004 +++ reopt/lib/LightWtProfiling/UnpackTraceFunction.cpp Tue Jun 8 13:53:56 2004 @@ -9,21 +9,21 @@ // // Pass to convert functions, which had previously been converted from // traces into functions, back into traces, and reattach them to the functions -// they came from. +// they came from. Runs *after* instruction selection and register allocation. // //===----------------------------------------------------------------------===// #include "reopt/UnpackTraceFunction.h" #include "reopt/TraceToFunction.h" -#include "reopt/MappingInfo.h" -#include "llvm/CodeGen/MachineFunctionInfo.h" +#include "reopt/MappingInfo.h" // for getBasicBlockInfo() +#include "llvm/CodeGen/InstrSelection.h" // for TmpInstruction +#include "llvm/CodeGen/MachineFunctionInfo.h" // for getStaticStackSize() +#include "llvm/CodeGen/MachineCodeForInstruction.h" #include "llvm/Module.h" -#include "llvm/Argument.h" #include "llvm/Assembly/Writer.h" -#include "llvm/Support/InstIterator.h" +#include "Support/StringExtras.h" // for utostr() #include "Support/Debug.h" #include "../../../../lib/Target/SparcV9/RegAlloc/AllocInfo.h" -#include "../../../../lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h" #include "../../../../lib/Target/SparcV9/SparcV9RegInfo.h" #include "../../../../lib/Target/SparcV9/SparcV9TargetMachine.h" @@ -127,7 +127,7 @@ DEBUG(std::cerr << "findRegsToSave: RegsToSave (size " << RegsToSave.size () << ") contains: ("; for (std::set::iterator i = RegsToSave.begin (), - e = RegsToSave.end (); i != e; ++i) { std::cerr << *i << " "; } + e = RegsToSave.end (); i != e; ++i) { std::cerr << RegStr (*i) << " "; } std::cerr << " )\n"); } @@ -136,24 +136,36 @@ return 2047 + StaticStackSize + 176 + R * 8; } +std::string UnpackTraceFunction::RegStr (const unsigned R) const { + static const char *RegTypeStrings[] = { "INT", "FPS", + "FPD", "INTCC", "FPCC", "SPCL" }; + const SparcV9RegInfo &TRI = *TM->getRegInfo (); + unsigned RegType = TRI.getRegType (R); + const char *RegName = TRI.getUnifiedRegName (R); + return std::string("reg#") + utostr(R) + "(" + RegTypeStrings[RegType] + ")=%" + RegName; +} + void UnpackTraceFunction::rewriteProlog (MachineFunction &MF, - MachineBasicBlock &E) { + MachineBasicBlock &EntryBB) { const SparcV9RegInfo &TRI = *TM->getRegInfo (); static const unsigned sp = SparcV9::o6, fp = SparcV9::i6, g1 = SparcV9::g1, g2 = SparcV9::g2; - // UTF prolog: start out by clearing everything out of the entry basic block - // (FIXME: may not work once we start doing optimizations!!! We will probably - // have to use a separate MBB) - E.clear (); + // UTF prolog: start out by clearing SAVE and stack-load instructions out + // of the entry BB. + while (EntryBB.front().getOpcode() == V9::SAVEi + || EntryBB.front().getOpcode() == V9::LDXi) + EntryBB.pop_front(); + + std::vector E; // 0. Save caller's stack pointer in %g1. - BuildMI (&E, V9::ORr, 3).addMReg (sp).addZImm (0) - .addMReg (g1, MachineOperand::Def); + E.push_back (BuildMI (V9::ORr, 3).addMReg (sp).addZImm (0) + .addMReg (g1, MachineOperand::Def)); // 1. Emit ADD instruction to allocate the right amount of stack space. - BuildMI (&E, V9::ADDi, 3).addMReg (sp).addSImm (-TotalStackSize) - .addMReg (sp, MachineOperand::Def); + E.push_back (BuildMI (V9::ADDi, 3).addMReg (sp).addSImm (-TotalStackSize) + .addMReg (sp, MachineOperand::Def)); // 2. Save used registers onto the stack. std::vector mvec; @@ -162,26 +174,16 @@ e = RegsToSave.end (); i != e; ++i) { mvec.clear (); unsigned R = *i; - unsigned RegType = TRI.getRegType (R); - - static const char *RegTypeStrings[] = { "IntRegType", "FPSingleRegType", - "FPDoubleRegType", "IntCCRegType", "FloatCCRegType", "SpecialRegType" }; - static const char *RegClassStrings[] = { "IntRegClassID", - "FloatRegClassID", "IntCCRegClassID", "FloatCCRegClassID", - "SpecialRegClassID" }; - DEBUG (std::cerr << "rewriteProlog: Saving reg#" << R << ", type = " - << RegType << " (" << RegTypeStrings[RegType] - << "), ClassID = " << TRI.getRegClassIDOfRegType(RegType) << " (" - << RegClassStrings[TRI.getRegClassIDOfRegType(RegType)] << ")\n"); - TRI.cpReg2MemMI (mvec, R, sp, stackOffsetForReg (R), RegType, g2); + DEBUG (std::cerr << "rewriteProlog: Saving " << RegStr (R) << "\n"); + TRI.cpReg2MemMI (mvec, R, sp, stackOffsetForReg (R), TRI.getRegType (R), g2); for (std::vector::iterator vi = mvec.begin (), ve = mvec.end (); vi != ve; ++vi) E.push_back (*vi); } // 3. Caller's stack pointer becomes our frame pointer. - BuildMI (&E, V9::ORr, 3).addMReg (g1).addZImm (0) - .addMReg (fp, MachineOperand::Def); + E.push_back (BuildMI (V9::ORr, 3).addMReg (g1).addZImm (0) + .addMReg (fp, MachineOperand::Def)); // 4. Insert a copy for each live-in variable to copy it from the stack // to the register that was allocated for it in the TraceFn. @@ -216,12 +218,43 @@ abort (); } } + + MachineBasicBlock::iterator MBBIt = EntryBB.begin (); + for (std::vector::iterator ei = E.begin (), ee = E.end (); ei != ee; ++ei) { + MBBIt = EntryBB.insert (MBBIt, *ei); + ++MBBIt; + } +} + +void UnpackTraceFunction::copyConstantToRegister (MachineFunction &MF, + Constant *C, unsigned Reg, + std::vector &mvec) { + const TargetInstrInfo &TII = *TM->getInstrInfo (); + TmpInstruction *tmp = new TmpInstruction (C); + TII.CreateCodeToLoadConst (*TM, const_cast (MF.getFunction ()), C, tmp, mvec, + MachineCodeForInstruction::get (tmp)); + DEBUG (for (std::vector::iterator i = mvec.begin (), e = mvec.end (); + i != e; ++i) + std::cerr << "copyConstantToRegister Input: " << **i << "\n"); + assert (mvec.size() == 1); + MachineInstr &theInst = *mvec.back(); + // note: this is pretty seriously hardwired for now. the problem is that in full + // generality, this is a little tiny episode of register allocation + assert (theInst.getOpcode () == V9::ORi + && theInst.getNumOperands () == 3 + && theInst.getOperand (2).isDef () + && theInst.getOperand (2).getType () == MachineOperand::MO_VirtualRegister); + theInst.SetRegForOperand (2, Reg); + DEBUG (for (std::vector::iterator i = mvec.begin (), e = mvec.end (); + i != e; ++i) + std::cerr << "copyConstantToRegister Output: " << **i << "\n"); } void UnpackTraceFunction::rewriteEpilog (MachineFunction &MF, MachineBasicBlock &MBB) { const SparcV9RegInfo &TRI = *TM->getRegInfo (); - static const unsigned fp = SparcV9::i6, sp = SparcV9::o6, g2 = SparcV9::g2; + static const unsigned fp = SparcV9::i6, sp = SparcV9::o6, g1 = SparcV9::g1, + g2 = SparcV9::g2; // UTF epilog: start out by clearing everything out of the exit basic block // (FIXME: may not work once we start doing optimizations!!! We will probably @@ -240,16 +273,31 @@ // Source is traceFn's register, Target is matrixFn's register AllocInfo &Target = ai.first, &Source = ai.second; assert (Target.AllocState == AllocInfo::Allocated - && Source.AllocState == AllocInfo::Allocated - && "FIXME: does not handle live-out values in stack slots yet"); + && "Live-out values must be in regs in the matrixFn"); mvec.clear (); - unsigned R = Source.Placement; - unsigned RegType = TRI.getRegType (R); - DEBUG (std::cerr << "rewriteEpilog: saving live-out value: " << V->getName() - << " is allocated to reg#" << Target.Placement - << " in MatrixFn and reg#" << Source.Placement << " in TraceFn\n"); - TRI.cpReg2MemMI (mvec, R, sp, stackOffsetForReg (Target.Placement), - RegType, g2); + if (Source.AllocState == AllocInfo::NotAllocated) { + assert (isa (TF->getCorrespondingValue (V, false)) + && "Can't handle non-constant, non-allocated live-out value in traceFn"); + copyConstantToRegister (MF, cast (TF->getCorrespondingValue (V, false)), + g1, mvec); + unsigned R = g1; + unsigned RegType = TRI.getRegType (R); + DEBUG (std::cerr << "rewriteEpilog: saving live-out value: " << V->getName() + << " is allocated to " << RegStr (Target.Placement) + << " in MatrixFn and is a constant in TraceFn\n"); + TRI.cpReg2MemMI (mvec, R, sp, stackOffsetForReg (Target.Placement), + RegType, g2); + } else { + assert (Source.AllocState == AllocInfo::Allocated + && "Can't handle live-out value spilled in traceFn"); + unsigned R = Source.Placement; + unsigned RegType = TRI.getRegType (R); + DEBUG (std::cerr << "rewriteEpilog: saving live-out value: " << V->getName() + << " is allocated to " << RegStr (Target.Placement) + << " in MatrixFn and " << RegStr (Source.Placement) << " in TraceFn\n"); + TRI.cpReg2MemMI (mvec, R, sp, stackOffsetForReg (Target.Placement), + RegType, g2); + } for (std::vector::iterator vi = mvec.begin (), ve = mvec.end (); vi != ve; ++vi) MBB.push_back (*vi); @@ -271,11 +319,8 @@ e = RegsToSave.end (); i != e; ++i) { mvec.clear (); unsigned R = *i; - unsigned RegType = TRI.getRegType (R); - DEBUG (std::cerr << "rewriteEpilog: Reloading reg#" << R << ", type = " - << RegType << ", " << "ClassID = " - << TRI.getRegClassIDOfRegType(RegType) << "\n"); - TRI.cpMem2RegMI (mvec, sp, stackOffsetForReg (R), R, RegType, g2); + DEBUG (std::cerr << "rewriteEpilog: Reloading " << RegStr (R) << "\n"); + TRI.cpMem2RegMI (mvec, sp, stackOffsetForReg (R), R, TRI.getRegType (R), g2); for (std::vector::iterator vi = mvec.begin (), ve = mvec.end (); vi != ve; ++vi) MBB.push_back (*vi); From gaeke at cs.uiuc.edu Tue Jun 8 13:55:15 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Jun 8 13:55:15 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/ValueAllocState.cpp Message-ID: <200406081854.NAA16074@kain.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: ValueAllocState.cpp updated: 1.2 -> 1.3 --- Log message: Never let getValueAllocStateKeys abort; just return (-1,-1) if it couldn't come up with the right keys. Fix callers to deal with this by returning a bogus AllocInfo object instead of aborting. --- Diffs of the changes: (+22 -22) Index: reopt/lib/LightWtProfiling/ValueAllocState.cpp diff -u reopt/lib/LightWtProfiling/ValueAllocState.cpp:1.2 reopt/lib/LightWtProfiling/ValueAllocState.cpp:1.3 --- reopt/lib/LightWtProfiling/ValueAllocState.cpp:1.2 Mon May 31 00:51:44 2004 +++ reopt/lib/LightWtProfiling/ValueAllocState.cpp Tue Jun 8 13:53:57 2004 @@ -93,19 +93,17 @@ /// static void getValueAllocStateKeys (Function *F, Value *V, int &InstructionKey, int &OperandKey, bool preferLiveIn) { + InstructionKey = -1; OperandKey = -1; if (Argument *Arg = dyn_cast (V)) { - InstructionKey = -1; OperandKey = getNumberOfFunctionArg (F, Arg); } else if (Instruction *Inst = dyn_cast (V)) { InstructionKey = getSavedStateIndexOfInstruction (F, Inst); if (isa (Inst) && preferLiveIn && Inst->getParent() == TraceEntryBB) - OperandKey = -2; // look for PhiCpRes - else - OperandKey = -1; + OperandKey = -2; // look for PhiCpRes instead. } else { - std::cerr << "getValueAllocStateKeys: can't look up state for " << *V; - abort(); + DEBUG (std::cerr << "getValueAllocStateKeys: keys not known for " + << F->getName () << ":" << *V << "\n"); } } @@ -116,12 +114,15 @@ /// static AllocInfo getValueAllocStateFromModule (Function *F, Value *V, bool preferLiveIn) { + int InstructionKey = -1, OperandKey = -1; + getValueAllocStateKeys (F, V, InstructionKey, OperandKey, preferLiveIn); + if (InstructionKey == -1 && OperandKey == -1) + return AllocInfo(); + unsigned FI = getLLVMFunctionPositionInfo (F); FunctionAllocState *FAllocState = _llvm_regAllocState.functions[FI]; assert (FAllocState->numTuples > 0 && "Reg. alloc state for function is empty"); - int InstructionKey = -1, OperandKey = -1; - getValueAllocStateKeys (F, V, InstructionKey, OperandKey, preferLiveIn); // Reconstruct the AllocInfo for V by searching // _llvm_regAllocState.functions[FI] for a tuple that starts with // (InstructionKey, OperandKey, ...): @@ -136,12 +137,10 @@ return AI; } } - // By this time we had better have found it, otherwise we are about to do bad - // things. - std::cerr << "ERROR: No saved AllocInfo found for " - << F->getName () << "()'s value " << *V - << " in getValueAllocStateFromModule()\n"; - abort (); + DEBUG (std::cerr << "Alloc state saved in module for " << F->getName () + << ":" << V->getName () << " (key = " << InstructionKey << "," + << OperandKey << ") NOT FOUND\n"); + return AllocInfo(); } /// Returns the register number or stack position where V can be found in the @@ -150,11 +149,14 @@ /// static AllocInfo getValueAllocStateFromGlobal (Function *F, Value *V, bool preferLiveIn) { + int InstructionKey = -1, OperandKey = -1; + getValueAllocStateKeys (F, V, InstructionKey, OperandKey, preferLiveIn); + if (InstructionKey == -1 && OperandKey == -1) + return AllocInfo(); + // Get the saved PhyRegAlloc state for F out of ExportedFnAllocState: std::vector &FState = ExportedFnAllocState[F]; assert (FState.size () > 0 && "Reg. alloc state for function is empty"); - int InstructionKey = -1, OperandKey = -1; - getValueAllocStateKeys (F, V, InstructionKey, OperandKey, preferLiveIn); // Reconstruct the AllocInfo for V by searching // FState for a tuple that starts with (InstructionKey, OperandKey, ...): for (unsigned i = 0, s = FState.size (); i < s; ++i) { @@ -166,12 +168,10 @@ return T; } } - // By this time we had better have found it, otherwise we are about to do bad - // things. - std::cerr << "ERROR: No saved AllocInfo found for " - << F->getName () << "()'s value " << *V - << " in getValueAllocStateFromGlobal()\n"; - abort (); + DEBUG (std::cerr << "Alloc state saved in global for " << F->getName () + << ":" << V->getName () << " (key = " << InstructionKey << "," + << OperandKey << ") NOT FOUND\n"); + return AllocInfo(); } /// GetValueAllocState - Returns a pair containing the From gaeke at cs.uiuc.edu Tue Jun 8 13:55:18 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Jun 8 13:55:18 2004 Subject: [llvm-commits] CVS: reopt/lib/TraceJIT/TraceJITGlobals.cpp Message-ID: <200406081854.NAA16088@kain.cs.uiuc.edu> Changes in directory reopt/lib/TraceJIT: TraceJITGlobals.cpp updated: 1.1 -> 1.2 --- Log message: Add lots of debugging printouts. --- Diffs of the changes: (+14 -5) Index: reopt/lib/TraceJIT/TraceJITGlobals.cpp diff -u reopt/lib/TraceJIT/TraceJITGlobals.cpp:1.1 reopt/lib/TraceJIT/TraceJITGlobals.cpp:1.2 --- reopt/lib/TraceJIT/TraceJITGlobals.cpp:1.1 Thu Jun 3 00:42:46 2004 +++ reopt/lib/TraceJIT/TraceJITGlobals.cpp Tue Jun 8 13:53:59 2004 @@ -28,13 +28,22 @@ namespace llvm { void TraceJIT::maybeAddInternalGlobal (GlobalValue *GV, unsigned int &Counter) { - if (Counter >= _llvm_internalGlobals.Size) return; + DEBUG (std::cerr << "maybeAddInternalGlobal: Looking for #" << Counter << ": " << GV->getName () << "\n"); + if (Counter >= _llvm_internalGlobals.Size) { + DEBUG (std::cerr << "maybeAddInternalGlobal: Walked off the end of InternalGlobals map: " << Counter << " >= " << _llvm_internalGlobals.Size << "\n"); + return; + } void *savedAddr = _llvm_internalGlobals.GlobalAddrs[Counter]; ++Counter; - if (GV->hasInternalLinkage() && GV->hasName () && savedAddr) { - DEBUG (std::cerr << "Old internal global " << GV->getName () - << " found at " << savedAddr << "\n"); - addGlobalMapping (GV, savedAddr); + if (GV->hasInternalLinkage() && GV->hasName ()) { + if (savedAddr) { + DEBUG (std::cerr << "maybeAddInternalGlobal: Old internal global " << GV->getName () << " found at " << savedAddr << "\n"); + addGlobalMapping (GV, savedAddr); + } else { + DEBUG (std::cerr << "maybeAddInternalGlobal: Old internal global " << GV->getName () << " NOT found (was null in map)!\n"); + } + } else { + DEBUG (std::cerr << "maybeAddInternalGlobal: Old global " << GV->getName () << " is not internal or does not have a name\n"); } } From gaeke at cs.uiuc.edu Tue Jun 8 13:55:22 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Jun 8 13:55:22 2004 Subject: [llvm-commits] CVS: reopt/lib/TraceToFunction/TraceToFunction.cpp Message-ID: <200406081854.NAA16095@kain.cs.uiuc.edu> Changes in directory reopt/lib/TraceToFunction: TraceToFunction.cpp updated: 1.60 -> 1.61 --- Log message: Fix up O2CMap correctly if we replace a value with a constant in fixupPhis(). --- Diffs of the changes: (+6 -1) Index: reopt/lib/TraceToFunction/TraceToFunction.cpp diff -u reopt/lib/TraceToFunction/TraceToFunction.cpp:1.60 reopt/lib/TraceToFunction/TraceToFunction.cpp:1.61 --- reopt/lib/TraceToFunction/TraceToFunction.cpp:1.60 Fri Jun 4 12:58:25 2004 +++ reopt/lib/TraceToFunction/TraceToFunction.cpp Tue Jun 8 13:54:00 2004 @@ -388,7 +388,12 @@ assert (i->first->use_size () == 0 && "Whoops, I was going to delete something which still has uses"); dstB->getInstList ().erase (i->first); - if (0) { O2CMap[i->first] = i->second; } else { assert (0 && "I don't think this is right - i->first is the real clone"); } + // We may have hosed the O2CMap with our replaceAllUses above. + // Fix it now. + for (ValueMap::iterator ii = O2CMap.begin (), ee = O2CMap.end (); + ii != ee; ++ii) + if (ii->second == i->first) + O2CMap[ii->first] = i->second; } } From gaeke at cs.uiuc.edu Tue Jun 8 15:09:02 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Jun 8 15:09:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/InternalGlobalMapper.cpp Message-ID: <200406082008.PAA17774@kain.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: InternalGlobalMapper.cpp updated: 1.1 -> 1.2 --- Log message: Fix a minor bug in the map - since this pass adds a global symbol, it must be accounted for in the map (at least, in its current format). --- Diffs of the changes: (+4 -0) Index: llvm/lib/Target/SparcV9/InternalGlobalMapper.cpp diff -u llvm/lib/Target/SparcV9/InternalGlobalMapper.cpp:1.1 llvm/lib/Target/SparcV9/InternalGlobalMapper.cpp:1.2 --- llvm/lib/Target/SparcV9/InternalGlobalMapper.cpp:1.1 Thu Jun 3 00:03:37 2004 +++ llvm/lib/Target/SparcV9/InternalGlobalMapper.cpp Tue Jun 8 15:08:30 2004 @@ -54,6 +54,10 @@ // Populate the vector with internal global values and their names. for (Module::giterator i = M.gbegin (), e = M.gend (); i != e; ++i) maybeAddInternalValueToVector (gvvector, *i); + // Add an extra global for _llvm_internalGlobals itself (null, + // because it's not internal) + gvvector.push_back (ConstantPointerNull::get + (PointerType::get (Type::SByteTy))); for (Module::iterator i = M.begin (), e = M.end (); i != e; ++i) maybeAddInternalValueToVector (gvvector, *i); From lattner at cs.uiuc.edu Tue Jun 8 16:56:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 16:56:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/LoopInfo.cpp Message-ID: <200406082150.QAA28980@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: LoopInfo.cpp updated: 1.55 -> 1.56 --- Log message: Don't grab the condition of unconditional branches! This fixes PR363: http://llvm.cs.uiuc.edu/PR363 --- Diffs of the changes: (+8 -7) Index: llvm/lib/Analysis/LoopInfo.cpp diff -u llvm/lib/Analysis/LoopInfo.cpp:1.55 llvm/lib/Analysis/LoopInfo.cpp:1.56 --- llvm/lib/Analysis/LoopInfo.cpp:1.55 Sun Apr 18 22:02:09 2004 +++ llvm/lib/Analysis/LoopInfo.cpp Tue Jun 8 16:50:30 2004 @@ -442,14 +442,15 @@ IV->getIncomingBlock(contains(IV->getIncomingBlock(1))); if (BranchInst *BI = dyn_cast(BackedgeBlock->getTerminator())) - if (SetCondInst *SCI = dyn_cast(BI->getCondition())) - if (SCI->getOperand(0) == Inc) - if (BI->getSuccessor(0) == getHeader()) { - if (SCI->getOpcode() == Instruction::SetNE) + if (BI->isConditional()) + if (SetCondInst *SCI = dyn_cast(BI->getCondition())) + if (SCI->getOperand(0) == Inc) + if (BI->getSuccessor(0) == getHeader()) { + if (SCI->getOpcode() == Instruction::SetNE) + return SCI->getOperand(1); + } else if (SCI->getOpcode() == Instruction::SetEQ) { return SCI->getOperand(1); - } else if (SCI->getOpcode() == Instruction::SetEQ) { - return SCI->getOperand(1); - } + } return 0; } From lattner at cs.uiuc.edu Tue Jun 8 17:08:03 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 17:08:03 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/iTerminators.h Message-ID: <200406082203.RAA31933@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: iTerminators.h updated: 1.42 -> 1.43 --- Log message: I checked and no clients expect this to return null for unconditional branches Simplify code and make it more uniform. --- Diffs of the changes: (+2 -1) Index: llvm/include/llvm/iTerminators.h diff -u llvm/include/llvm/iTerminators.h:1.42 llvm/include/llvm/iTerminators.h:1.43 --- llvm/include/llvm/iTerminators.h:1.42 Wed May 26 17:07:18 2004 +++ llvm/include/llvm/iTerminators.h Tue Jun 8 17:03:05 2004 @@ -126,7 +126,8 @@ inline bool isConditional() const { return Operands.size() == 3; } inline Value *getCondition() const { - return isUnconditional() ? 0 : reinterpret_cast(Operands[2].get()); + assert(isConditional() && "Cannot get condition of an uncond branch!"); + return Operands[2].get(); } void setCondition(Value *V) { From lattner at cs.uiuc.edu Tue Jun 8 18:27:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 18:27:02 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200406082321.SAA03889@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.89 -> 1.90 --- Log message: Workaround or a VS miscompilation bug --- Diffs of the changes: (+1 -1) Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.89 llvm/lib/VMCore/Constants.cpp:1.90 --- llvm/lib/VMCore/Constants.cpp:1.89 Fri Jun 4 18:52:36 2004 +++ llvm/lib/VMCore/Constants.cpp Tue Jun 8 18:21:39 2004 @@ -442,7 +442,7 @@ case Type::ShortTyID: return (Val <= INT16_MAX && Val >= INT16_MIN); case Type::IntTyID: - return (Val <= INT32_MAX && Val >= INT32_MIN); + return (Val <= int(INT32_MAX) && Val >= int(INT32_MIN)); case Type::LongTyID: return true; // This is the largest type... } From lattner at cs.uiuc.edu Tue Jun 8 20:11:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 20:11:02 2004 Subject: [llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c Message-ID: <200406090110.UAA15836@apoc.cs.uiuc.edu> Changes in directory llvm-gcc/gcc: llvm-expand.c updated: 1.40 -> 1.41 --- Log message: Cleanup patch to make llvmgcc compile with GCC 3.4. Contributed by Markus F.X.J. Oberhumer --- Diffs of the changes: (+6 -4) Index: llvm-gcc/gcc/llvm-expand.c diff -u llvm-gcc/gcc/llvm-expand.c:1.40 llvm-gcc/gcc/llvm-expand.c:1.41 --- llvm-gcc/gcc/llvm-expand.c:1.40 Wed Jun 2 13:44:20 2004 +++ llvm-gcc/gcc/llvm-expand.c Tue Jun 8 20:10:16 2004 @@ -59,6 +59,8 @@ static void llvm_expand_decl_cleanup(llvm_function *Fn, tree decl, tree cleanup, int eh_only); +static void llvm_expand_expr_stmt_value(llvm_function *Fn, tree exp, + int isLast); extern int isPassedByInvisibleReference(tree Type); @@ -4992,12 +4994,12 @@ *BufPtr++ = '0'; *BufPtr++ = 'x'; if (!(BYTES_BIG_ENDIAN)) { /* If little endian */ - sprintf(Buffer+2, "%08X", RealArr[1]); - sprintf(Buffer+10, "%08X", RealArr[0]); + sprintf(Buffer+2, "%08lX", RealArr[1]); + sprintf(Buffer+10, "%08lX", RealArr[0]); *(Buffer+18) = 0; /* Null terminate */ } else { - sprintf(Buffer+2, "%08X", RealArr[0]); - sprintf(Buffer+10, "%08X", RealArr[1]); + sprintf(Buffer+2, "%08lX", RealArr[0]); + sprintf(Buffer+10, "%08lX", RealArr[1]); *(Buffer+18) = 0; /* Null terminate */ } From lattner at cs.uiuc.edu Tue Jun 8 20:14:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 20:14:01 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200406090109.UAA06400@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.196 -> 1.197 --- Log message: Bug fixed --- Diffs of the changes: (+3 -1) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.196 llvm/docs/ReleaseNotes.html:1.197 --- llvm/docs/ReleaseNotes.html:1.196 Tue Jun 8 02:30:31 2004 +++ llvm/docs/ReleaseNotes.html Tue Jun 8 20:09:16 2004 @@ -182,6 +182,8 @@ -disable/enable-povray and -disable-spec
  • shell scripts output by gccld don't work if you change PATH
  • +
  • [llvmgcc] llvmgcc does not compile +with gcc 3.4
  • @@ -710,7 +712,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/06/08 07:30:31 $ + Last modified: $Date: 2004/06/09 01:09:16 $ From llvm at cs.uiuc.edu Tue Jun 8 21:13:02 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Tue Jun 8 21:13:02 2004 Subject: [llvm-commits] CVS: llvm/utils/NightlyTestTemplate.html Message-ID: <200406090207.VAA06646@zion.cs.uiuc.edu> Changes in directory llvm/utils: NightlyTestTemplate.html updated: 1.25 -> 1.26 --- Log message: Regularize title of Regression Test section. Clean up some blank space. --- Diffs of the changes: (+2 -4) Index: llvm/utils/NightlyTestTemplate.html diff -u llvm/utils/NightlyTestTemplate.html:1.25 llvm/utils/NightlyTestTemplate.html:1.26 --- llvm/utils/NightlyTestTemplate.html:1.25 Mon May 31 16:38:56 2004 +++ llvm/utils/NightlyTestTemplate.html Tue Jun 8 21:07:25 2004 @@ -249,11 +249,9 @@

    Regression Tests +Regression Test Results

    $RegressionTestResults - - - + From lattner at cs.uiuc.edu Tue Jun 8 23:04:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 23:04:02 2004 Subject: [llvm-commits] CVS: llvm/docs/GarbageCollection.html Message-ID: <200406090359.WAA07667@zion.cs.uiuc.edu> Changes in directory llvm/docs: GarbageCollection.html updated: 1.4 -> 1.5 --- Log message: Minor tweaks --- Diffs of the changes: (+5 -4) Index: llvm/docs/GarbageCollection.html diff -u llvm/docs/GarbageCollection.html:1.4 llvm/docs/GarbageCollection.html:1.5 --- llvm/docs/GarbageCollection.html:1.4 Thu May 27 00:52:10 2004 +++ llvm/docs/GarbageCollection.html Tue Jun 8 22:59:05 2004 @@ -220,7 +220,7 @@

    The llvm_gc_allocate function is a global function defined by the -garbage collector implementation to allocate memory. It should return a +garbage collector implementation to allocate memory. It returns a zeroed-out block of memory of the appropriate size.

    @@ -242,8 +242,9 @@ collection) reads or writes object references into the heap. In the case of a generational collector, it needs to keep track of which "old" generation objects have references stored into them. The amount of code that typically needs to be -executed is usually quite small, so the overall performance impact of the -inserted code is tolerable.

    +executed is usually quite small (and not on the critical path of any +computation), so the overall performance impact of the inserted code is +tolerable.

    To support garbage collectors that use read or write barriers, LLVM provides the llvm.gcread and llvm.gcwrite intrinsics. The first @@ -519,7 +520,7 @@ Chris Lattner
    LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/05/27 05:52:10 $ + Last modified: $Date: 2004/06/09 03:59:05 $ From lattner at cs.uiuc.edu Tue Jun 8 23:29:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 23:29:02 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/select.ll Message-ID: <200406090424.XAA08257@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: select.ll updated: 1.6 -> 1.7 --- Log message: New testcase for the instruction combiner that happen often in the Java FE --- Diffs of the changes: (+13 -0) Index: llvm/test/Regression/Transforms/InstCombine/select.ll diff -u llvm/test/Regression/Transforms/InstCombine/select.ll:1.6 llvm/test/Regression/Transforms/InstCombine/select.ll:1.7 --- llvm/test/Regression/Transforms/InstCombine/select.ll:1.6 Sat Apr 10 17:21:14 2004 +++ llvm/test/Regression/Transforms/InstCombine/select.ll Tue Jun 8 23:23:57 2004 @@ -96,3 +96,16 @@ %V = select bool %C, int %b, int %a ret int %V } + +bool %test14a(bool %C, int %X) { + %V = select bool %C, int %X, int 0 + %R = setlt int %V, 1 ; (X < 1) | !C + ret bool %R +} + +bool %test14b(bool %C, int %X) { + %V = select bool %C, int 0, int %X + %R = setlt int %V, 1 ; (X < 1) | C + ret bool %R +} + From lattner at cs.uiuc.edu Tue Jun 8 23:30:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Jun 8 23:30:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200406090424.XAA08268@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.206 -> 1.207 --- Log message: Implement select.ll:test14* --- Diffs of the changes: (+59 -35) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.206 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.207 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.206 Thu May 27 12:30:27 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Tue Jun 8 23:24:29 2004 @@ -1471,44 +1471,68 @@ return BinaryOperator::create(Instruction::Or, Not, Op1); } - // Check to see if we are doing one of many comparisons against constant - // integers at the end of their ranges... - // + // See if we are doing a comparison between a constant and an instruction that + // can be folded into the comparison. if (ConstantInt *CI = dyn_cast(Op1)) { if (Instruction *LHSI = dyn_cast(Op0)) - if (LHSI->hasOneUse() && LHSI->getNumOperands() == 2 && - isa(LHSI->getOperand(1))) { - // If this is: (X >> C1) & C2 != C3 (where any shift and any compare - // could exist), turn it into (X & (C2 << C1)) != (C3 << C1). This - // happens a LOT in code produced by the C front-end, for bitfield - // access. - if (LHSI->getOpcode() == Instruction::And && - LHSI->getOperand(0)->hasOneUse()) - if (ShiftInst *Shift = dyn_cast(LHSI->getOperand(0))) - if (ConstantUInt *ShAmt = - dyn_cast(Shift->getOperand(1))) { - ConstantInt *AndCST = cast(LHSI->getOperand(1)); - - // We can fold this as long as we can't shift unknown bits into - // the mask. This can only happen with signed shift rights, as - // they sign-extend. - const Type *Ty = Shift->getType(); - if (Shift->getOpcode() != Instruction::Shr || - Shift->getType()->isUnsigned() || - // To test for the bad case of the signed shr, see if any of - // the bits shifted in could be tested after the mask. - ConstantExpr::getAnd(ConstantExpr::getShl(ConstantInt::getAllOnesValue(Ty), ConstantUInt::get(Type::UByteTy, Ty->getPrimitiveSize()*8-ShAmt->getValue())), AndCST)->isNullValue()) { - unsigned ShiftOp = Shift->getOpcode() == Instruction::Shl - ? Instruction::Shr : Instruction::Shl; - I.setOperand(1, ConstantExpr::get(ShiftOp, CI, ShAmt)); - LHSI->setOperand(1, ConstantExpr::get(ShiftOp, AndCST, ShAmt)); - LHSI->setOperand(0, Shift->getOperand(0)); - WorkList.push_back(Shift); // Shift is probably dead. - AddUsesToWorkList(I); - return &I; + if (LHSI->hasOneUse()) + if (LHSI->getNumOperands() == 2 && + isa(LHSI->getOperand(1))) { + // If this is: (X >> C1) & C2 != C3 (where any shift and any compare + // could exist), turn it into (X & (C2 << C1)) != (C3 << C1). This + // happens a LOT in code produced by the C front-end, for bitfield + // access. + if (LHSI->getOpcode() == Instruction::And && + LHSI->getOperand(0)->hasOneUse()) + if (ShiftInst *Shift = dyn_cast(LHSI->getOperand(0))) + if (ConstantUInt *ShAmt = + dyn_cast(Shift->getOperand(1))) { + ConstantInt *AndCST = cast(LHSI->getOperand(1)); + + // We can fold this as long as we can't shift unknown bits into + // the mask. This can only happen with signed shift rights, as + // they sign-extend. + const Type *Ty = Shift->getType(); + if (Shift->getOpcode() != Instruction::Shr || + Shift->getType()->isUnsigned() || + // To test for the bad case of the signed shr, see if any of + // the bits shifted in could be tested after the mask. + ConstantExpr::getAnd(ConstantExpr::getShl(ConstantInt::getAllOnesValue(Ty), ConstantUInt::get(Type::UByteTy, Ty->getPrimitiveSize()*8-ShAmt->getValue())), AndCST)->isNullValue()) { + unsigned ShiftOp = Shift->getOpcode() == Instruction::Shl + ? Instruction::Shr : Instruction::Shl; + I.setOperand(1, ConstantExpr::get(ShiftOp, CI, ShAmt)); + LHSI->setOperand(1, ConstantExpr::get(ShiftOp, AndCST,ShAmt)); + LHSI->setOperand(0, Shift->getOperand(0)); + WorkList.push_back(Shift); // Shift is probably dead. + AddUsesToWorkList(I); + return &I; + } } - } - } + + } else if (SelectInst *SI = dyn_cast(LHSI)) { + // If either operand of the select is a constant, we can fold the + // comparison into the select arms, which will cause one to be + // constant folded and the select turned into a bitwise or. + Value *Op1 = 0, *Op2 = 0; + if (Constant *C = dyn_cast(SI->getOperand(1))) { + // Fold the known value into the constant operand. + Op1 = ConstantExpr::get(I.getOpcode(), C, CI); + // Insert a new SetCC of the other select operand. + Op2 = InsertNewInstBefore(new SetCondInst(I.getOpcode(), + SI->getOperand(2), CI, + I.getName()), I); + } else if (Constant *C = dyn_cast(SI->getOperand(2))) { + // Fold the known value into the constant operand. + Op2 = ConstantExpr::get(I.getOpcode(), C, CI); + // Insert a new SetCC of the other select operand. + Op1 = InsertNewInstBefore(new SetCondInst(I.getOpcode(), + SI->getOperand(1), CI, + I.getName()), I); + } + + if (Op1) + return new SelectInst(SI->getCondition(), Op1, Op2); + } // Simplify seteq and setne instructions... if (I.getOpcode() == Instruction::SetEQ || From llvm at cs.uiuc.edu Tue Jun 8 23:44:01 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Tue Jun 8 23:44:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Internal/SlotTable.h Message-ID: <200406090438.XAA09359@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Internal: SlotTable.h (r1.2) removed --- Log message: Cleaned up a dead header file to prevent duplicate definition warnings in doxygen. --- Diffs of the changes: (+0 -0) From llvm at cs.uiuc.edu Tue Jun 8 23:44:05 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Tue Jun 8 23:44:05 2004 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Writer/SlotTable.cpp Message-ID: <200406090438.XAA09364@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Writer: SlotTable.cpp updated: 1.3 -> 1.4 --- Log message: Cleaned up a dead header file to prevent duplicate definition warnings in doxygen. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Bytecode/Writer/SlotTable.cpp diff -u llvm/lib/Bytecode/Writer/SlotTable.cpp:1.3 llvm/lib/Bytecode/Writer/SlotTable.cpp:1.4 --- llvm/lib/Bytecode/Writer/SlotTable.cpp:1.3 Tue May 25 15:09:05 2004 +++ llvm/lib/Bytecode/Writer/SlotTable.cpp Tue Jun 8 23:38:34 2004 @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Internal/SlotTable.h" +#include "SlotTable.h" #include "llvm/Constants.h" #include "llvm/Type.h" #include "llvm/GlobalValue.h" From lattner at cs.uiuc.edu Wed Jun 9 00:12:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Jun 9 00:12:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/JavaCompare.ll Message-ID: <200406090507.AAA10081@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: JavaCompare.ll added (r1.1) --- Log message: New testcase that is important for the Java FE --- Diffs of the changes: (+14 -0) Index: llvm/test/Regression/Transforms/InstCombine/JavaCompare.ll diff -c /dev/null llvm/test/Regression/Transforms/InstCombine/JavaCompare.ll:1.1 *** /dev/null Wed Jun 9 00:07:11 2004 --- llvm/test/Regression/Transforms/InstCombine/JavaCompare.ll Wed Jun 9 00:07:01 2004 *************** *** 0 **** --- 1,14 ---- + ; This is the sequence of stuff that the Java front-end expands for a single + ; <= comparison. Check to make sure we turn it into a <= (only) + + ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep -v setle | not grep '#uses' + + bool %le(int %A, int %B) { + %c1 = setgt int %A, %B; + %tmp = select bool %c1, int 1, int 0; + %c2 = setlt int %A, %B; + %result = select bool %c2, int -1, int %tmp; + %c3 = setle int %result, 0; + ret bool %c3; + } + From lattner at cs.uiuc.edu Wed Jun 9 00:13:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Jun 9 00:13:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200406090508.AAA10091@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.207 -> 1.208 --- Log message: Be more careful about the order we put stuff onto the worklist. This allow us to collapse this: bool %le(int %A, int %B) { %c1 = setgt int %A, %B %tmp = select bool %c1, int 1, int 0 %c2 = setlt int %A, %B %result = select bool %c2, int -1, int %tmp %c3 = setle int %result, 0 ret bool %c3 } into: bool %le(int %A, int %B) { %c3 = setle int %A, %B ; [#uses=1] ret bool %c3 } which is handy, because the Java FE makes these sequences all over the place. This is tested as: test/Regression/Transforms/InstCombine/JavaCompare.ll --- Diffs of the changes: (+19 -19) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.207 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.208 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.207 Tue Jun 8 23:24:29 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Wed Jun 9 00:08:07 2004 @@ -704,7 +704,8 @@ (Op1I->getOperand(0) == Op0 || Op1I->getOperand(1) == Op0)) { Value *OtherOp = Op1I->getOperand(Op1I->getOperand(0) == Op0); - Instruction *NewNot = BinaryOperator::createNot(OtherOp, "B.not", &I); + Value *NewNot = + InsertNewInstBefore(BinaryOperator::createNot(OtherOp, "B.not"), I); return BinaryOperator::create(Instruction::And, Op0, NewNot); } @@ -1249,10 +1250,9 @@ // (~A | ~B) == (~(A & B)) - Demorgan's Law if (Op0NotVal && Op1NotVal && isOnlyUse(Op0) && isOnlyUse(Op1)) { - Instruction *And = BinaryOperator::create(Instruction::And, Op0NotVal, - Op1NotVal,I.getName()+".demorgan", - &I); - WorkList.push_back(And); + Value *And = InsertNewInstBefore( + BinaryOperator::create(Instruction::And, Op0NotVal, + Op1NotVal,I.getName()+".demorgan"), I); return BinaryOperator::createNot(And); } @@ -1374,8 +1374,8 @@ if (Op0I->getOperand(0) == Op1) // (B|A)^B == (A|B)^B cast(Op0I)->swapOperands(); if (Op0I->getOperand(1) == Op1) { // (A|B)^B == A & ~B - Value *NotB = BinaryOperator::createNot(Op1, Op1->getName()+".not", &I); - WorkList.push_back(cast(NotB)); + Value *NotB = InsertNewInstBefore(BinaryOperator::createNot(Op1, + Op1->getName()+".not"), I); return BinaryOperator::create(Instruction::And, Op0I->getOperand(0), NotB); } @@ -1508,7 +1508,6 @@ return &I; } } - } else if (SelectInst *SI = dyn_cast(LHSI)) { // If either operand of the select is a constant, we can fold the // comparison into the select arms, which will cause one to be @@ -3051,9 +3050,12 @@ DEBUG(std::cerr << "IC: Old = " << *I << " New = " << *Result); - // Instructions can end up on the worklist more than once. Make sure - // we do not process an instruction that has been deleted. - removeFromWorkList(I); + // Everything uses the new instruction now. + I->replaceAllUsesWith(Result); + + // Push the new instruction and any users onto the worklist. + WorkList.push_back(Result); + AddUsersToWorkList(*Result); // Move the name to the new instruction first... std::string OldName = I->getName(); I->setName(""); @@ -3069,8 +3071,9 @@ if (Instruction *OpI = dyn_cast(I->getOperand(i))) WorkList.push_back(OpI); - // Everything uses the new instruction now... - I->replaceAllUsesWith(Result); + // Instructions can end up on the worklist more than once. Make sure + // we do not process an instruction that has been deleted. + removeFromWorkList(I); // Erase the old instruction. InstParent->getInstList().erase(I); @@ -3090,14 +3093,11 @@ // occurrances of this instruction. removeFromWorkList(I); I->getParent()->getInstList().erase(I); - Result = 0; + } else { + WorkList.push_back(Result); + AddUsersToWorkList(*Result); } } - - if (Result) { - WorkList.push_back(Result); - AddUsersToWorkList(*Result); - } Changed = true; } } From llvm at cs.uiuc.edu Wed Jun 9 01:20:01 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Wed Jun 9 01:20:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Analyzer/Parser.cpp Message-ID: <200406090615.BAA11720@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Analyzer: Parser.cpp updated: 1.2 -> 1.3 --- Log message: Bring some things out of header files that belong only in this file. --- Diffs of the changes: (+21 -0) Index: llvm/lib/Bytecode/Analyzer/Parser.cpp diff -u llvm/lib/Bytecode/Analyzer/Parser.cpp:1.2 llvm/lib/Bytecode/Analyzer/Parser.cpp:1.3 --- llvm/lib/Bytecode/Analyzer/Parser.cpp:1.2 Tue Jun 8 00:54:47 2004 +++ llvm/lib/Bytecode/Analyzer/Parser.cpp Wed Jun 9 01:14:52 2004 @@ -17,6 +17,7 @@ //===----------------------------------------------------------------------===// #include "AnalyzerInternals.h" +#include "ReaderPrimitives.h" #include "llvm/Module.h" #include "llvm/Bytecode/Format.h" #include "Support/StringExtras.h" @@ -25,6 +26,17 @@ using namespace llvm; +// Enable to trace to figure out what the heck is going on when parsing fails +//#define TRACE_LEVEL 10 +//#define DEBUG_OUTPUT + +#if TRACE_LEVEL // ByteCodeReading_TRACEr +#define BCR_TRACE(n, X) \ + if (n < TRACE_LEVEL) std::cerr << std::string(n*2, ' ') << X +#else +#define BCR_TRACE(n, X) +#endif + #define PARSE_ERROR(inserters) \ { \ std::ostringstream errormsg; \ @@ -32,6 +44,15 @@ if ( ! handler->handleError( errormsg.str() ) ) \ throw std::string(errormsg.str()); \ } + + +inline void AbstractBytecodeParser::readBlock(const unsigned char *&Buf, + const unsigned char *EndBuf, + unsigned &Type, unsigned &Size) +{ + Type = read(Buf, EndBuf); + Size = read(Buf, EndBuf); +} const Type *AbstractBytecodeParser::getType(unsigned ID) { //cerr << "Looking up Type ID: " << ID << "\n"; From llvm at cs.uiuc.edu Wed Jun 9 01:21:02 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Wed Jun 9 01:21:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Analyzer/AnalyzerInternals.h Message-ID: <200406090615.BAA11735@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Analyzer: AnalyzerInternals.h updated: 1.2 -> 1.3 --- Log message: Move parsing details to Parser.cpp. --- Diffs of the changes: (+0 -25) Index: llvm/lib/Bytecode/Analyzer/AnalyzerInternals.h diff -u llvm/lib/Bytecode/Analyzer/AnalyzerInternals.h:1.2 llvm/lib/Bytecode/Analyzer/AnalyzerInternals.h:1.3 --- llvm/lib/Bytecode/Analyzer/AnalyzerInternals.h:1.2 Tue Jun 8 00:52:29 2004 +++ llvm/lib/Bytecode/Analyzer/AnalyzerInternals.h Wed Jun 9 01:15:21 2004 @@ -14,33 +14,14 @@ #ifndef ANALYZER_INTERNALS_H #define ANALYZER_INTERNALS_H -#include "ReaderPrimitives.h" #include "Parser.h" #include "llvm/Bytecode/Analyzer.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" -// Enable to trace to figure out what the heck is going on when parsing fails -//#define TRACE_LEVEL 10 -//#define DEBUG_OUTPUT - -#if TRACE_LEVEL // ByteCodeReading_TRACEr -#define BCR_TRACE(n, X) \ - if (n < TRACE_LEVEL) std::cerr << std::string(n*2, ' ') << X -#else -#define BCR_TRACE(n, X) -#endif namespace llvm { -inline void AbstractBytecodeParser::readBlock(const unsigned char *&Buf, - const unsigned char *EndBuf, - unsigned &Type, unsigned &Size) -{ - Type = read(Buf, EndBuf); - Size = read(Buf, EndBuf); -} - class BytecodeAnalyzer { BytecodeAnalyzer(const BytecodeAnalyzer &); // DO NOT IMPLEMENT void operator=(const BytecodeAnalyzer &); // DO NOT IMPLEMENT @@ -61,12 +42,6 @@ BytecodeAnalysis& bca, const std::string &ModuleID ); - - void dump() const { - std::cerr << "BytecodeParser instance!\n"; - } -private: - BytecodeAnalysis TheAnalysis; }; } // End llvm namespace From llvm at cs.uiuc.edu Wed Jun 9 01:21:10 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Wed Jun 9 01:21:10 2004 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Analyzer/Dumper.cpp Message-ID: <200406090616.BAA11763@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Analyzer: Dumper.cpp updated: 1.1 -> 1.2 --- Log message: Clean up indentation of file body output. Don't dump functions unless "detailedResults" is requested. --- Diffs of the changes: (+10 -9) Index: llvm/lib/Bytecode/Analyzer/Dumper.cpp diff -u llvm/lib/Bytecode/Analyzer/Dumper.cpp:1.1 llvm/lib/Bytecode/Analyzer/Dumper.cpp:1.2 --- llvm/lib/Bytecode/Analyzer/Dumper.cpp:1.1 Mon Jun 7 12:53:43 2004 +++ llvm/lib/Bytecode/Analyzer/Dumper.cpp Wed Jun 9 01:16:19 2004 @@ -190,23 +190,23 @@ GlobalValue::LinkageTypes linkage ) { - std::cout << " BLOCK: Function {\n"; - std::cout << " Linkage: " << linkage << "\n"; - std::cout << " Type: " << FType->getDescription() << "\n"; + std::cout << "BLOCK: Function {\n"; + std::cout << " Linkage: " << linkage << "\n"; + std::cout << " Type: " << FType->getDescription() << "\n"; } virtual void handleFunctionEnd( const Type* FType ) { - std::cout << " } END BLOCK: Function\n"; + std::cout << "} END BLOCK: Function\n"; } virtual void handleBasicBlockBegin( unsigned blocknum ) { - std::cout << " BLOCK: BasicBlock #" << blocknum << "{\n"; + std::cout << " BLOCK: BasicBlock #" << blocknum << "{\n"; } virtual bool handleInstruction( @@ -215,18 +215,18 @@ std::vector& Operands ) { - std::cout << " INST: OpCode=" + std::cout << " INST: OpCode=" << Instruction::getOpcodeName(Opcode) << " Type=" << iType->getDescription() << "\n"; for ( unsigned i = 0; i < Operands.size(); ++i ) - std::cout << " Op#" << i << " Slot=" << Operands[i] << "\n"; + std::cout << " Op#" << i << " Slot=" << Operands[i] << "\n"; return Instruction::isTerminator(Opcode); } virtual void handleBasicBlockEnd(unsigned blocknum) { - std::cout << " } END BLOCK: BasicBlock #" << blocknum << "{\n"; + std::cout << " } END BLOCK: BasicBlock #" << blocknum << "{\n"; } virtual void handleGlobalConstantsBegin() @@ -305,7 +305,8 @@ BytecodeDumper TheHandler; AbstractBytecodeParser TheParser(&TheHandler); TheParser.ParseBytecode( Buf, Length, ModuleID ); - TheParser.ParseAllFunctionBodies(); + if ( bca.detailedResults ) + TheParser.ParseAllFunctionBodies(); } // vim: sw=2 From llvm at cs.uiuc.edu Wed Jun 9 01:22:03 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Wed Jun 9 01:22:03 2004 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Analyzer/Analyzer.cpp Message-ID: <200406090616.BAA11775@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Analyzer: Analyzer.cpp updated: 1.1 -> 1.2 --- Log message: Implement some rudimentary analysis. --- Diffs of the changes: (+47 -3) Index: llvm/lib/Bytecode/Analyzer/Analyzer.cpp diff -u llvm/lib/Bytecode/Analyzer/Analyzer.cpp:1.1 llvm/lib/Bytecode/Analyzer/Analyzer.cpp:1.2 --- llvm/lib/Bytecode/Analyzer/Analyzer.cpp:1.1 Mon Jun 7 12:53:43 2004 +++ llvm/lib/Bytecode/Analyzer/Analyzer.cpp Wed Jun 9 01:16:43 2004 @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "AnalyzerInternals.h" +#include using namespace llvm; @@ -20,22 +21,49 @@ namespace { class AnalyzerHandler : public BytecodeHandler { + BytecodeAnalysis& bca; public: + AnalyzerHandler(BytecodeAnalysis& TheBca) + : bca(TheBca) + { + } + bool handleError(const std::string& str ) { + std::cerr << "Analysis Error: " << str; return false; } void handleStart() { + bca.ModuleId.clear(); + bca.numTypes = 0; + bca.numValues = 0; + bca.numFunctions = 0; + bca.numConstants = 0; + bca.numGlobalVars = 0; + bca.numInstructions = 0; + bca.numBasicBlocks = 0; + bca.numOperands = 0; + bca.numCmpctnTables = 0; + bca.numSymTab = 0; + bca.maxTypeSlot = 0; + bca.maxValueSlot = 0; + bca.density = 0.0; + bca.FunctionInfo.clear(); + bca.BytecodeDump.clear(); } void handleFinish() { + bca.density = bca.numTypes + bca.numFunctions + bca.numConstants + + bca.numGlobalVars + bca.numInstructions; + bca.density /= bca.byteSize; } void handleModuleBegin(const std::string& id) { + bca.ModuleId = id; } void handleModuleEnd(const std::string& id) @@ -60,6 +88,7 @@ GlobalValue::LinkageTypes ///< The linkage type of the GV ) { + bca.numGlobalVars++; } void handleInitializedGV( @@ -69,16 +98,19 @@ unsigned initSlot ///< Slot number of GV's initializer ) { + bca.numGlobalVars++; } virtual void handleType( const Type* Ty ) { + bca.numTypes++; } void handleFunctionDeclaration( const Type* FuncType ///< The type of the function ) { + bca.numFunctions++; } void handleModuleGlobalsEnd() @@ -94,6 +126,7 @@ unsigned NumEntries ) { + bca.numCmpctnTables++; } void handleCompactionTableType( @@ -118,6 +151,7 @@ void handleSymbolTableBegin() { + bca.numSymTab++; } void handleSymbolTablePlane( @@ -165,6 +199,7 @@ unsigned blocknum ) { + bca.numBasicBlocks++; } bool handleInstruction( @@ -173,7 +208,8 @@ std::vector& Operands ) { - return false; + bca.numInstructions++; + return Instruction::isTerminator(Opcode); } void handleBasicBlockEnd(unsigned blocknum) @@ -190,31 +226,37 @@ std::vector > ArgVec ) { + bca.numConstants++; } void handleConstantValue( Constant * c ) { + bca.numConstants++; } void handleConstantArray( const ArrayType* AT, std::vector& Elements ) { + bca.numConstants++; } void handleConstantStruct( const StructType* ST, std::vector& ElementSlots) { + bca.numConstants++; } void handleConstantPointer( const PointerType* PT, unsigned Slot) { + bca.numConstants++; } void handleConstantString( const ConstantArray* CA ) { + bca.numConstants++; } @@ -233,10 +275,12 @@ const std::string &ModuleID ) { - AnalyzerHandler TheHandler; + bca.byteSize = Length; + AnalyzerHandler TheHandler(bca); AbstractBytecodeParser TheParser(&TheHandler); TheParser.ParseBytecode( Buf, Length, ModuleID ); - TheParser.ParseAllFunctionBodies(); + if ( bca.detailedResults ) + TheParser.ParseAllFunctionBodies(); } // vim: sw=2 From llvm at cs.uiuc.edu Wed Jun 9 01:23:03 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Wed Jun 9 01:23:03 2004 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp Message-ID: <200406090618.BAA11794@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Analyzer: AnalyzerWrappers.cpp updated: 1.1 -> 1.2 --- Log message: Implement analysis output. Don't dump function details unless requested. --- Diffs of the changes: (+20 -1) Index: llvm/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp diff -u llvm/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp:1.1 llvm/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp:1.2 --- llvm/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp:1.1 Mon Jun 7 12:53:43 2004 +++ llvm/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp Wed Jun 9 01:17:58 2004 @@ -202,7 +202,26 @@ /// @brief Print BytecodeAnalysis structure to an ostream void llvm::PrintBytecodeAnalysis(BytecodeAnalysis& bca, std::ostream& Out ) { - Out << "Not Implemented Yet.\n"; + Out << "Bytecode Analysis of " << bca.ModuleId << "\n"; + Out << " File Size:" << bca.byteSize << "\n"; + Out << " Number Of Types:" << bca.numTypes << "\n"; + Out << " Number Of Constants:" << bca.numConstants << "\n"; + Out << " Number Of Global Variables:" << bca.numGlobalVars << "\n"; + Out << " Number Of Functions:" << bca.numFunctions << "\n"; + Out << " Number Of Basic Blocks:" << bca.numBasicBlocks << "\n"; + Out << " Number Of Instructions:" << bca.numInstructions << "\n"; + Out << " Number Of Operands:" << bca.numOperands << "\n"; + Out << "Number Of Compaction Tables:" << bca.numCmpctnTables << "\n"; + Out << " Number Of Symbol Tables:" << bca.numSymTab << "\n"; + Out << " Maximum Type Slot Number:" << bca.maxTypeSlot << "\n"; + Out << " Maximum Value Slot Number:" << bca.maxValueSlot << "\n"; + Out << " Bytecode Density:" << bca.density << "\n"; + + if ( bca.detailedResults ) + Out << "Detailed Results Not Implemented Yet.\n"; + + if ( bca.dumpBytecode ) + Out << bca.BytecodeDump; } // vim: sw=2 From llvm at cs.uiuc.edu Wed Jun 9 01:24:00 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Wed Jun 9 01:24:00 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Bytecode/Analyzer.h Message-ID: <200406090619.BAA11816@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Bytecode: Analyzer.h updated: 1.3 -> 1.4 --- Log message: Add some new fields for bytecode analysis. --- Diffs of the changes: (+4 -1) Index: llvm/include/llvm/Bytecode/Analyzer.h diff -u llvm/include/llvm/Bytecode/Analyzer.h:1.3 llvm/include/llvm/Bytecode/Analyzer.h:1.4 --- llvm/include/llvm/Bytecode/Analyzer.h:1.3 Tue Jun 8 08:49:17 2004 +++ llvm/include/llvm/Bytecode/Analyzer.h Wed Jun 9 01:18:53 2004 @@ -29,7 +29,8 @@ /// results. /// @brief Bytecode Analysis results structure struct BytecodeAnalysis { - unsigned byteSize; ///< The size of the bytecode file in bytes + std::string ModuleId; ///< Identification of the module + unsigned byteSize; ///< The size of the bytecode file in bytes unsigned numTypes; ///< The number of types unsigned numValues; ///< The number of values unsigned numFunctions; ///< The number of functions defined @@ -38,6 +39,8 @@ unsigned numInstructions; ///< The number of instructions in all functions unsigned numBasicBlocks; ///< The number of BBs in all functions unsigned numOperands; ///< The number of BBs in all functions + unsigned numCmpctnTables; ///< The number of compaction tables + unsigned numSymTab; ///< The number of symbol tables unsigned maxTypeSlot; ///< The maximum slot number for types unsigned maxValueSlot; ///< The maximum slot number for values double density; ///< Density of file (bytes/defs) From llvm at cs.uiuc.edu Wed Jun 9 01:27:02 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Wed Jun 9 01:27:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp Message-ID: <200406090622.BAA11834@zion.cs.uiuc.edu> Changes in directory llvm/lib/Bytecode/Analyzer: AnalyzerWrappers.cpp updated: 1.2 -> 1.3 --- Log message: Cleanup alignment of output. --- Diffs of the changes: (+14 -14) Index: llvm/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp diff -u llvm/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp:1.2 llvm/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp:1.3 --- llvm/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp:1.2 Wed Jun 9 01:17:58 2004 +++ llvm/lib/Bytecode/Analyzer/AnalyzerWrappers.cpp Wed Jun 9 01:22:00 2004 @@ -202,20 +202,20 @@ /// @brief Print BytecodeAnalysis structure to an ostream void llvm::PrintBytecodeAnalysis(BytecodeAnalysis& bca, std::ostream& Out ) { - Out << "Bytecode Analysis of " << bca.ModuleId << "\n"; - Out << " File Size:" << bca.byteSize << "\n"; - Out << " Number Of Types:" << bca.numTypes << "\n"; - Out << " Number Of Constants:" << bca.numConstants << "\n"; - Out << " Number Of Global Variables:" << bca.numGlobalVars << "\n"; - Out << " Number Of Functions:" << bca.numFunctions << "\n"; - Out << " Number Of Basic Blocks:" << bca.numBasicBlocks << "\n"; - Out << " Number Of Instructions:" << bca.numInstructions << "\n"; - Out << " Number Of Operands:" << bca.numOperands << "\n"; - Out << "Number Of Compaction Tables:" << bca.numCmpctnTables << "\n"; - Out << " Number Of Symbol Tables:" << bca.numSymTab << "\n"; - Out << " Maximum Type Slot Number:" << bca.maxTypeSlot << "\n"; - Out << " Maximum Value Slot Number:" << bca.maxValueSlot << "\n"; - Out << " Bytecode Density:" << bca.density << "\n"; + Out << " Bytecode Analysis of: " << bca.ModuleId << "\n"; + Out << " File Size: " << bca.byteSize << "\n"; + Out << " Number Of Types: " << bca.numTypes << "\n"; + Out << " Number Of Constants: " << bca.numConstants << "\n"; + Out << " Number Of Global Variables: " << bca.numGlobalVars << "\n"; + Out << " Number Of Functions: " << bca.numFunctions << "\n"; + Out << " Number Of Basic Blocks: " << bca.numBasicBlocks << "\n"; + Out << " Number Of Instructions: " << bca.numInstructions << "\n"; + Out << " Number Of Operands: " << bca.numOperands << "\n"; + Out << "Number Of Compaction Tables: " << bca.numCmpctnTables << "\n"; + Out << " Number Of Symbol Tables: " << bca.numSymTab << "\n"; + Out << " Maximum Type Slot Number: " << bca.maxTypeSlot << "\n"; + Out << " Maximum Value Slot Number: " << bca.maxValueSlot << "\n"; + Out << " Bytecode Density: " << bca.density << "\n"; if ( bca.detailedResults ) Out << "Detailed Results Not Implemented Yet.\n"; From lattner at cs.uiuc.edu Wed Jun 9 03:05:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Jun 9 03:05:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/select.ll Message-ID: <200406090759.CAA26145@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: select.ll updated: 1.7 -> 1.8 --- Log message: More instcombine testcases --- Diffs of the changes: (+27 -0) Index: llvm/test/Regression/Transforms/InstCombine/select.ll diff -u llvm/test/Regression/Transforms/InstCombine/select.ll:1.7 llvm/test/Regression/Transforms/InstCombine/select.ll:1.8 --- llvm/test/Regression/Transforms/InstCombine/select.ll:1.7 Tue Jun 8 23:23:57 2004 +++ llvm/test/Regression/Transforms/InstCombine/select.ll Wed Jun 9 02:59:40 2004 @@ -109,3 +109,30 @@ ret bool %R } +int %test15a(int %X) { ;; Code sequence for (X & 16) ? 16 : 0 + %t1 = and int %X, 16 + %t2 = seteq int %t1, 0 + %t3 = select bool %t2, int 0, int 16 ;; X & 16 + ret int %t3 +} + +int %test15b(int %X) { ;; Code sequence for (X & 32) ? 0 : 24 + %t1 = and int %X, 32 + %t2 = seteq int %t1, 0 + %t3 = select bool %t2, int 32, int 0 ;; ~X & 32 + ret int %t3 +} + +int %test15c(int %X) { ;; Alternate code sequence for (X & 16) ? 16 : 0 + %t1 = and int %X, 16 + %t2 = seteq int %t1, 16 + %t3 = select bool %t2, int 16, int 0 ;; X & 16 + ret int %t3 +} + +int %test15d(int %X) { ;; Alternate code sequence for (X & 16) ? 16 : 0 + %t1 = and int %X, 16 + %t2 = setne int %t1, 0 + %t3 = select bool %t2, int 16, int 0 ;; X & 16 + ret int %t3 +} From lattner at cs.uiuc.edu Wed Jun 9 03:05:07 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Jun 9 03:05:07 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200406090800.DAA26154@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.208 -> 1.209 --- Log message: Implement InstCombine/select.ll:test15* --- Diffs of the changes: (+90 -40) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.208 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.209 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.208 Wed Jun 9 00:08:07 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Wed Jun 9 02:59:58 2004 @@ -934,6 +934,13 @@ return CS->getValue() == Val+1; } +// isOneBitSet - Return true if there is exactly one bit set in the specified +// constant. +static bool isOneBitSet(const ConstantInt *CI) { + uint64_t V = CI->getRawValue(); + return V && (V & (V-1)) == 0; +} + /// getSetCondCode - Encode a setcc opcode into a three bit mask. These bits /// are carefully arranged to allow folding of expressions such as: /// @@ -1063,17 +1070,17 @@ // Adding a one to a single bit bit-field should be turned into an XOR // of the bit. First thing to check is to see if this AND is with a // single bit constant. - unsigned long long AndRHSV = cast(AndRHS)->getRawValue(); + uint64_t AndRHSV = cast(AndRHS)->getRawValue(); // Clear bits that are not part of the constant. AndRHSV &= (1ULL << AndRHS->getType()->getPrimitiveSize()*8)-1; // If there is only one bit set... - if ((AndRHSV & (AndRHSV-1)) == 0) { + if (isOneBitSet(cast(AndRHS))) { // Ok, at this point, we know that we are masking the result of the // ADD down to exactly one bit. If the constant we are adding has // no bits set below this bit, then we can eliminate the ADD. - unsigned long long AddRHS = cast(OpRHS)->getRawValue(); + uint64_t AddRHS = cast(OpRHS)->getRawValue(); // Check to see if any bits below the one bit set in AndRHSV are set. if ((AddRHS & (AndRHSV-1)) == 0) { @@ -1476,61 +1483,66 @@ if (ConstantInt *CI = dyn_cast(Op1)) { if (Instruction *LHSI = dyn_cast(Op0)) if (LHSI->hasOneUse()) - if (LHSI->getNumOperands() == 2 && - isa(LHSI->getOperand(1))) { - // If this is: (X >> C1) & C2 != C3 (where any shift and any compare - // could exist), turn it into (X & (C2 << C1)) != (C3 << C1). This - // happens a LOT in code produced by the C front-end, for bitfield - // access. - if (LHSI->getOpcode() == Instruction::And && - LHSI->getOperand(0)->hasOneUse()) - if (ShiftInst *Shift = dyn_cast(LHSI->getOperand(0))) - if (ConstantUInt *ShAmt = - dyn_cast(Shift->getOperand(1))) { - ConstantInt *AndCST = cast(LHSI->getOperand(1)); - - // We can fold this as long as we can't shift unknown bits into - // the mask. This can only happen with signed shift rights, as - // they sign-extend. - const Type *Ty = Shift->getType(); - if (Shift->getOpcode() != Instruction::Shr || - Shift->getType()->isUnsigned() || - // To test for the bad case of the signed shr, see if any of - // the bits shifted in could be tested after the mask. - ConstantExpr::getAnd(ConstantExpr::getShl(ConstantInt::getAllOnesValue(Ty), ConstantUInt::get(Type::UByteTy, Ty->getPrimitiveSize()*8-ShAmt->getValue())), AndCST)->isNullValue()) { - unsigned ShiftOp = Shift->getOpcode() == Instruction::Shl - ? Instruction::Shr : Instruction::Shl; - I.setOperand(1, ConstantExpr::get(ShiftOp, CI, ShAmt)); - LHSI->setOperand(1, ConstantExpr::get(ShiftOp, AndCST,ShAmt)); - LHSI->setOperand(0, Shift->getOperand(0)); - WorkList.push_back(Shift); // Shift is probably dead. - AddUsesToWorkList(I); - return &I; + switch (LHSI->getOpcode()) { + case Instruction::And: + if (isa(LHSI->getOperand(1))) { + + + // If this is: (X >> C1) & C2 != C3 (where any shift and any compare + // could exist), turn it into (X & (C2 << C1)) != (C3 << C1). This + // happens a LOT in code produced by the C front-end, for bitfield + // access. + if (LHSI->getOperand(0)->hasOneUse()) + if (ShiftInst *Shift = dyn_cast(LHSI->getOperand(0))) + if (ConstantUInt *ShAmt = + dyn_cast(Shift->getOperand(1))) { + ConstantInt *AndCST = cast(LHSI->getOperand(1)); + + // We can fold this as long as we can't shift unknown bits + // into the mask. This can only happen with signed shift + // rights, as they sign-extend. + const Type *Ty = Shift->getType(); + if (Shift->getOpcode() != Instruction::Shr || + Shift->getType()->isUnsigned() || + // To test for the bad case of the signed shr, see if any + // of the bits shifted in could be tested after the mask. + ConstantExpr::getAnd(ConstantExpr::getShl(ConstantInt::getAllOnesValue(Ty), ConstantUInt::get(Type::UByteTy, Ty->getPrimitiveSize()*8-ShAmt->getValue())), AndCST)->isNullValue()) { + unsigned ShiftOp = Shift->getOpcode() == Instruction::Shl + ? Instruction::Shr : Instruction::Shl; + I.setOperand(1, ConstantExpr::get(ShiftOp, CI, ShAmt)); + LHSI->setOperand(1,ConstantExpr::get(ShiftOp,AndCST,ShAmt)); + LHSI->setOperand(0, Shift->getOperand(0)); + WorkList.push_back(Shift); // Shift is probably dead. + AddUsesToWorkList(I); + return &I; + } } - } - } else if (SelectInst *SI = dyn_cast(LHSI)) { + } + break; + case Instruction::Select: // If either operand of the select is a constant, we can fold the // comparison into the select arms, which will cause one to be // constant folded and the select turned into a bitwise or. Value *Op1 = 0, *Op2 = 0; - if (Constant *C = dyn_cast(SI->getOperand(1))) { + if (Constant *C = dyn_cast(LHSI->getOperand(1))) { // Fold the known value into the constant operand. Op1 = ConstantExpr::get(I.getOpcode(), C, CI); // Insert a new SetCC of the other select operand. Op2 = InsertNewInstBefore(new SetCondInst(I.getOpcode(), - SI->getOperand(2), CI, + LHSI->getOperand(2), CI, I.getName()), I); - } else if (Constant *C = dyn_cast(SI->getOperand(2))) { + } else if (Constant *C = dyn_cast(LHSI->getOperand(2))) { // Fold the known value into the constant operand. Op2 = ConstantExpr::get(I.getOpcode(), C, CI); // Insert a new SetCC of the other select operand. Op1 = InsertNewInstBefore(new SetCondInst(I.getOpcode(), - SI->getOperand(1), CI, + LHSI->getOperand(1), CI, I.getName()), I); } if (Op1) - return new SelectInst(SI->getCondition(), Op1, Op2); + return new SelectInst(LHSI->getOperand(0), Op1, Op2); + break; } // Simplify seteq and setne instructions... @@ -1592,6 +1604,16 @@ NotConstant(BOC))->isNullValue()) return ReplaceInstUsesWith(I, ConstantBool::get(isSetNE)); + // If we have ((X & C) == C), turn it into ((X & C) != 0). + if (CI == BOC) { + // Don't infinite loop if C is null and the & isn't folded yet. + if (CI->isNullValue()) + return ReplaceInstUsesWith(I, ConstantBool::get(!isSetNE)); + return new SetCondInst(isSetNE ? Instruction::SetEQ : + Instruction::SetNE, Op0, + Constant::getNullValue(CI->getType())); + } + // Replace (and X, (1 << size(X)-1) != 0) with x < 0, converting X // to be a signed value as appropriate. if (isSignBit(BOC)) { @@ -2258,6 +2280,34 @@ "not."+CondVal->getName()), SI); return new CastInst(NotCond, SI.getType()); } + + // If one of the constants is zero (we know they can't both be) and we + // have a setcc instruction with zero, and we have an 'and' with the + // non-constant value, eliminate this whole mess. This corresponds to + // cases like this: ((X & 27) ? 27 : 0) + if (TrueValC->isNullValue() || FalseValC->isNullValue()) + if (Instruction *IC = dyn_cast(SI.getCondition())) + if ((IC->getOpcode() == Instruction::SetEQ || + IC->getOpcode() == Instruction::SetNE) && + isa(IC->getOperand(1)) && + cast(IC->getOperand(1))->isNullValue()) + if (Instruction *ICA = dyn_cast(IC->getOperand(0))) + if (ICA->getOpcode() == Instruction::And && + isa(ICA->getOperand(1)) && + (ICA->getOperand(1) == TrueValC || + ICA->getOperand(1) == FalseValC) && + isOneBitSet(cast(ICA->getOperand(1)))) { + // Okay, now we know that everything is set up, we just don't + // know whether we have a setne or seteq and whether the true or + // false val is the zero. + bool ShouldNotVal = !TrueValC->isNullValue(); + ShouldNotVal ^= IC->getOpcode() == Instruction::SetNE; + Value *V = ICA; + if (ShouldNotVal) + V = InsertNewInstBefore(BinaryOperator::create( + Instruction::Xor, V, ICA->getOperand(1)), SI); + return ReplaceInstUsesWith(SI, V); + } } // See if we are selecting two values based on a comparison of the two values. From criswell at cs.uiuc.edu Wed Jun 9 10:20:01 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Wed Jun 9 10:20:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200406091519.KAA27762@choi.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.257 -> 1.258 --- Log message: Fix for PR#366. We use getClassB() so that we can handle cast instructions that cast to bool. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.257 llvm/lib/Target/X86/InstSelectSimple.cpp:1.258 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.257 Wed Jun 2 00:55:25 2004 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Wed Jun 9 10:18:51 2004 @@ -2861,7 +2861,7 @@ case Instruction::Cast: // If this is a cast from a signed-integer type to a floating point type, // fold the cast here. - if (getClass(User->getType()) == cFP && + if (getClassB(User->getType()) == cFP && (I.getType() == Type::ShortTy || I.getType() == Type::IntTy || I.getType() == Type::LongTy)) { unsigned DestReg = getReg(User); From llvm at cs.uiuc.edu Wed Jun 9 10:32:01 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Wed Jun 9 10:32:01 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/AsmWriter.cpp Message-ID: <200406091527.KAA11701@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AsmWriter.cpp updated: 1.136 -> 1.137 --- Log message: Made it possible for the printInfoComment method to invoke getSlot in such a way that if the Value being printed is standalone that we don't assert and abort but just print ":??" for the slot number instead. --- Diffs of the changes: (+16 -17) Index: llvm/lib/VMCore/AsmWriter.cpp diff -u llvm/lib/VMCore/AsmWriter.cpp:1.136 llvm/lib/VMCore/AsmWriter.cpp:1.137 --- llvm/lib/VMCore/AsmWriter.cpp:1.136 Fri Jun 4 18:53:20 2004 +++ llvm/lib/VMCore/AsmWriter.cpp Wed Jun 9 10:26:53 2004 @@ -74,7 +74,10 @@ /// Return the slot number of the specified value in it's type /// plane. Its an error to ask for something not in the SlotMachine. /// Its an error to ask for a Type* - unsigned getSlot(const Value *V) ; + unsigned getSlot(const Value *V, bool ignoreMissing = false ) ; + + /// Determine if a Value has a slot or not + bool hasSlot(const Value* V); /// @} /// @name Mutators @@ -883,13 +886,17 @@ printType(V.getType()) << '>'; if (!V.hasName()) { - *Out << ':' << Machine.getSlot(&V); // Print out the def slot taken. + unsigned SlotNum = Machine.getSlot(&V,true); + if ( unsigned(-1) == SlotNum ) + *Out << ":??"; + else + *Out << ':' << SlotNum; // Print out the def slot taken. } *Out << " [#uses=" << V.use_size() << ']'; // Output # uses } } -/// printInstruction - This member is called for each Instruction in a method. +/// printInstruction - This member is called for each Instruction in a function.. /// void AssemblyWriter::printInstruction(const Instruction &I) { if (AnnotationWriter) AnnotationWriter->emitInstructionAnnot(&I, *Out); @@ -1266,7 +1273,7 @@ /// Get the slot number for a value. This function will assert if you /// ask for a Value that hasn't previously been inserted with createSlot. /// Types are forbidden because Type does not inherit from Value (any more). -unsigned SlotMachine::getSlot(const Value *V) { +unsigned SlotMachine::getSlot(const Value *V, bool ignoreMissing ) { assert( V && "Can't get slot for null Value" ); assert( !isa(V) && "Can't get slot for a type" ); assert(!isa(V) || isa(V) && @@ -1297,6 +1304,7 @@ // Look up the value in the module map ValueMap::const_iterator MVI = MI->second.map.find(V); // If we didn't find it, it wasn't inserted + if ( ignoreMissing && MVI == MI->second.map.end()) return unsigned(-1); assert( MVI != MI->second.map.end() && "Value not found"); // We found it only at the module level return MVI->second; @@ -1308,32 +1316,23 @@ // to the type plane. return MI->second.next_slot + FVI->second; } - - // else there is not a corresponding type plane in the function map - } else { - assert( MI != mMap.end() && "No such type plane!" ); - // Look up the value in the module's map - ValueMap::const_iterator MVI = MI->second.map.find(V); - // If we didn't find it, it wasn't inserted. - assert( MVI != MI->second.map.end() && "Value not found"); - // We found it only in the module level and function level - // didn't even have a type plane. - return MVI->second; } } - // N.B. Can only get here if !TheFunction + // N.B. Can get here only if either !TheFunction or the function doesn't + // have a corresponding type plane for the Value // Make sure the type plane exists + if ( ignoreMissing && MI == mMap.end()) return unsigned(-1); assert( MI != mMap.end() && "No such type plane!" ); // Lookup the value in the module's map ValueMap::const_iterator MVI = MI->second.map.find(V); // Make sure we found it. + if ( ignoreMissing && MVI == MI->second.map.end()) return unsigned(-1); assert( MVI != MI->second.map.end() && "Value not found" ); // Return it. return MVI->second; } - // Create a new slot, or return the existing slot if it is already // inserted. Note that the logic here parallels getSlot but instead From lattner at cs.uiuc.edu Wed Jun 9 13:34:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Jun 9 13:34:02 2004 Subject: [llvm-commits] CVS: llvm/utils/fpcmp/fpcmp.cpp Message-ID: <200406091829.NAA20185@zion.cs.uiuc.edu> Changes in directory llvm/utils/fpcmp: fpcmp.cpp updated: 1.6 -> 1.7 --- Log message: Fix the really bizarre stuff that happened last night in the tester due to non-numeric diff failures that caused fpcmp to go into infinite loops --- Diffs of the changes: (+14 -2) Index: llvm/utils/fpcmp/fpcmp.cpp diff -u llvm/utils/fpcmp/fpcmp.cpp:1.6 llvm/utils/fpcmp/fpcmp.cpp:1.7 --- llvm/utils/fpcmp/fpcmp.cpp:1.6 Thu May 27 19:35:51 2004 +++ llvm/utils/fpcmp/fpcmp.cpp Wed Jun 9 13:28:53 2004 @@ -54,6 +54,10 @@ } static char *BackupNumber(char *Pos, char *FirstChar) { + // If we didn't stop in the middle of a number, don't backup. + if (!isNumberChar(*Pos)) return Pos; + + // Otherwise, return to the start of the number. while (Pos > FirstChar && isNumberChar(Pos[-1])) --Pos; return Pos; @@ -61,8 +65,16 @@ static void CompareNumbers(char *&F1P, char *&F2P, char *F1End, char *F2End) { char *F1NumEnd, *F2NumEnd; - double V1 = strtod(F1P, &F1NumEnd); - double V2 = strtod(F2P, &F2NumEnd); + double V1, V2; + // If we stop on numbers, compare their difference. + if (isNumberChar(*F1P) && isNumberChar(*F2P)) { + V1 = strtod(F1P, &F1NumEnd); + V2 = strtod(F2P, &F2NumEnd); + } else { + // Otherwise, the diff failed. + F1NumEnd = F1P; + F2NumEnd = F2P; + } if (F1NumEnd == F1P || F2NumEnd == F2P) { std::cerr << "Comparison failed, not a numeric difference.\n"; From llvm at cs.uiuc.edu Wed Jun 9 13:35:02 2004 From: llvm at cs.uiuc.edu (LLVM) Date: Wed Jun 9 13:35:02 2004 Subject: [llvm-commits] CVS: llvm/utils/NightlyTestTemplate.html Message-ID: <200406091829.NAA20197@zion.cs.uiuc.edu> Changes in directory llvm/utils: NightlyTestTemplate.html updated: 1.26 -> 1.27 --- Log message: Columnized the compilation statistics for easier reading. --- Diffs of the changes: (+254 -257) Index: llvm/utils/NightlyTestTemplate.html diff -u llvm/utils/NightlyTestTemplate.html:1.26 llvm/utils/NightlyTestTemplate.html:1.27 --- llvm/utils/NightlyTestTemplate.html:1.26 Tue Jun 8 21:07:25 2004 +++ llvm/utils/NightlyTestTemplate.html Wed Jun 9 13:29:15 2004 @@ -1,257 +1,254 @@ - - -LLVM Test Results for $DateString - - -

    LLVM Test Results for $DateString
    -
    - - -
    - -
    -
    -Sections:
    -
    -Overview
    -Changes
    -Trends
    -Programs
    -Feature
    -Regression
    -
    - -

    -
    -
    Previous:
    -
    - $PrevDaysList -
    -

    - -Back to:
    -Test Results
    -LLVM Page

    - -

    - -
    -
    -
    Today's Test Results Overview -

    - - - - - -
    - -
    Lines Of Code over Time
    -Click for larger view -
    - -

    CVS Tree Overview:

    -
      -
    • CVS Checkout Log -
        - $NumDirsInCVS dirs, $NumFilesInCVS files, $LOC - lines of code, checked out in $CVSCheckoutTime seconds
      -
    • Compilation Log -
        - $BuildError - Time to configure CVS tree: $ConfigTime seconds - ($ConfigWallTime seconds wall time)
        - Time to build CVS tree: $BuildTime seconds - ($BuildWallTime seconds wall time)
        - Time to run feature tests: $FeatureTime seconds - ($FeatureWallTime seconds wall time)
        - Time to run regression tests: $RegressionTime seconds - ($RegressionWallTime seconds wall time)
        - Number of object files compiled: $NumObjects
        - Number of libraries linked: $NumLibraries
        - Number of executables linked: $NumExecutables
        -
      -
    - -

    Warnings during the build:

    -
      $WarningsList -

    - -

    -
    -
    Changes from Yesterday -

    - -

    Changes to CVS:

    -
      -
    • Users who committed to CVS: $UserCommitList -
    • Users who updated from CVS: $UserUpdateList -
    • Added Files: $AddedFilesList -
    • Modified Files: $ModifiedFilesList -
    • Removed Files: $RemovedFilesList -

    - -

    Changes to Warnings:

    -
      -
    • Warnings Added: $WarningsAdded -
    • Warnings Removed: $WarningsRemoved -

    - -

    Changes in the test suite:

    -
      -
    • New Tests: $TestsAdded -
    • Removed Tests: $TestsRemoved -
    • Newly passing tests: $TestsFixed -
    • Newly failing tests: $TestsBroken -
    -
    -

    -
    -
    Changes Over Time -

    - - -Here are some charts showing how the LLVM optimizer and code generators are -changing over time. For now we use the Olden benchmark suite to measure this, -but eventually we will switch to using SPEC CPU2000. All programs are run with -"LARGE_PROBLEM_SIZE" enabled. Click on any of the charts to get a larger -version.

    - -

    Compilation Measurements:

    - - - - - - - - -
    -
    -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:

    - - - - - - - - - -
    -
    -Execution time for CBE generated executable -
    -
    -Execution time for the LLC generated executable -
    -
    -Execution time for program in the JIT -
    - - - - -

    -
    -
    Program Tests -

    - -This section tests LLVM on a variety of programs in the test suite. This -includes benchmark suites like the Olden, McCat, Ptrdist, and SPEC benchmarks as -well as a few random programs with test inputs. This section is meant to track -how stable LLVM is as a whole. A failure in the execution of any test is marked -with an asterisk: `*'. The columns of the tables are:

    - -

      -
    1. Program - The name of the program for that row.
    2. -
    3. GCCAS - Time to run LLVM optimizers on the program.
    4. -
    5. Bytecode - The size of the bytecode for the - program
    6. -
    7. Instrs - The number of LLVM instructions in the - compiled bytecode
    8. -
    9. LLC compile - The time taken compile with - LLC (the static backend)
    10. -
    11. JIT codegen - The amount of time spent in the - JIT itself, instead of executing the program.
    12. -
    13. Machine code - The number of bytes of machine - code generated by the JIT.
    14. -
    15. GCC - The time taken to execute the program when compiled - with GCC -O2.
    16. -
    17. CBE - The time taken to execute the program after - compilation through the C backend, compiled with -O2.
    18. -
    19. LLC - How long does the program generated by the static - backend LLC take to execute
    20. -
    21. JIT - The amount of time spent running the - program with the JIT; this includes the code generation phase (listed above) - and actually running the program.
    22. -
    23. GCC/LLC - The speed-up of the LLC output vs the native - GCC output: greater than 1 is a speedup, less than 1 is a slowdown.
    24. -
    25. GCC/CBE - The speed-up of the CBE output vs the native - GCC output: greater than 1 is a speedup, less than 1 is a slowdown.
    26. -
    27. LLC-LS - How long does the program generated by the static - backend LLC take to execute the program, when compiled with the linear scan - register allocator. This is temporary, for tuning.
    28. -

    - -A complete log of testing -SingleSource, -MultiSource, and -External programs are -available for further analysis. - -

    Programs/External

    - -
    -
    -$ExternalProgramsTable -
    - -

    Programs/MultiSource

    - -
    -
    -$MultiSourceProgramsTable -
    - -

    Programs/SingleSource

    - -
    -
    -$SingleSourceProgramsTable -
    - - - -

    -
    -
    Feature Test Results -
    -
    -$FeatureTestResults - -

    -
    -
    Regression Test Results -
    -
    -$RegressionTestResults - - + + +LLVM Test Results for $DateString + + +
    LLVM Test Results for $DateString
    +
    + + +
    + +
    +
    +Sections:
    +
    +Overview
    +Changes
    +Trends
    +Programs
    +Feature
    +Regression
    +
    + +

    +
    +
    Previous:
    +
    + $PrevDaysList +
    +

    + +Back to:
    +Test Results
    +LLVM Page

    + +

    + +
    +
    +
    Today's Test Results Overview +

    + + + + + +
    + +
    Lines Of Code over Time
    +Click for larger view +
    + +

    CVS Tree Overview:

    +
      +
    • CVS Checkout Log +
        + $NumDirsInCVS dirs, $NumFilesInCVS files, $LOC + lines of code, checked out in $CVSCheckoutTime seconds
      +
    • Compilation Log + + + + + + +
      ItemCPU TimeWall Clock
      Configure CVS Tree$ConfigTime$ConfigWallTime
      Build CVS Tree$BuildTime$BuildWallTime
      Run Feature Tests$FeatureTime$FeatureWallTime
      Run Regression Tests$RegressionTime$RegressionWallTime
    • +
    • Number of object files compiled: $NumObjects
    • +
    • Number of libraries linked: $NumLibraries
    • +
    • Number of executables linked: $NumExecutables
    • +
    • Build Error: $BuildError
    • +
    + +

    Warnings during the build:

    +
      $WarningsList +

    + +

    +
    +
    Changes from Yesterday +

    + +

    Changes to CVS:

    +
      +
    • Users who committed to CVS: $UserCommitList +
    • Users who updated from CVS: $UserUpdateList +
    • Added Files: $AddedFilesList +
    • Modified Files: $ModifiedFilesList +
    • Removed Files: $RemovedFilesList +

    + +

    Changes to Warnings:

    +
      +
    • Warnings Added: $WarningsAdded +
    • Warnings Removed: $WarningsRemoved +

    + +

    Changes in the test suite:

    +
      +
    • New Tests: $TestsAdded +
    • Removed Tests: $TestsRemoved +
    • Newly passing tests: $TestsFixed +
    • Newly failing tests: $TestsBroken +
    +
    +

    +
    +
    Changes Over Time +

    + + +Here are some charts showing how the LLVM optimizer and code generators are +changing over time. For now we use the Olden benchmark suite to measure this, +but eventually we will switch to using SPEC CPU2000. All programs are run with +"LARGE_PROBLEM_SIZE" enabled. Click on any of the charts to get a larger +version.

    + +

    Compilation Measurements:

    + + + + + + + + +
    +
    +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:

    + + + + + + + + + +
    +
    +Execution time for CBE generated executable +
    +
    +Execution time for the LLC generated executable +
    +
    +Execution time for program in the JIT +
    + + + + +

    +
    +
    Program Tests +

    + +This section tests LLVM on a variety of programs in the test suite. This +includes benchmark suites like the Olden, McCat, Ptrdist, and SPEC benchmarks as +well as a few random programs with test inputs. This section is meant to track +how stable LLVM is as a whole. A failure in the execution of any test is marked +with an asterisk: `*'. The columns of the tables are:

    + +

      +
    1. Program - The name of the program for that row.
    2. +
    3. GCCAS - Time to run LLVM optimizers on the program.
    4. +
    5. Bytecode - The size of the bytecode for the + program
    6. +
    7. Instrs - The number of LLVM instructions in the + compiled bytecode
    8. +
    9. LLC compile - The time taken compile with + LLC (the static backend)
    10. +
    11. JIT codegen - The amount of time spent in the + JIT itself, instead of executing the program.
    12. +
    13. Machine code - The number of bytes of machine + code generated by the JIT.
    14. +
    15. GCC - The time taken to execute the program when compiled + with GCC -O2.
    16. +
    17. CBE - The time taken to execute the program after + compilation through the C backend, compiled with -O2.
    18. +
    19. LLC - How long does the program generated by the static + backend LLC take to execute
    20. +
    21. JIT - The amount of time spent running the + program with the JIT; this includes the code generation phase (listed above) + and actually running the program.
    22. +
    23. GCC/LLC - The speed-up of the LLC output vs the native + GCC output: greater than 1 is a speedup, less than 1 is a slowdown.
    24. +
    25. GCC/CBE - The speed-up of the CBE output vs the native + GCC output: greater than 1 is a speedup, less than 1 is a slowdown.
    26. +
    27. LLC-LS - How long does the program generated by the static + backend LLC take to execute the program, when compiled with the linear scan + register allocator. This is temporary, for tuning.
    28. +

    + +A complete log of testing +SingleSource, +MultiSource, and +External programs are +available for further analysis. + +

    Programs/External

    + +
    +
    +$ExternalProgramsTable +
    + +

    Programs/MultiSource

    + +
    +
    +$MultiSourceProgramsTable +
    + +

    Programs/SingleSource

    + +
    +
    +$SingleSourceProgramsTable +
    + + + +

    +
    +
    Feature Test Results +
    +
    +$FeatureTestResults + +

    +
    +
    Regression Test Results +
    +
    +$RegressionTestResults + + From lattner at cs.uiuc.edu Wed Jun 9 14:47:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Jun 9 14:47:02 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/AsmWriter.cpp Message-ID: <200406091941.OAA29252@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: AsmWriter.cpp updated: 1.137 -> 1.138 --- Log message: Make the asmwriter much more tolerant of errors (which are common when working on new front-ends and stuff). Also get rid of some tabs that snuck in. --- Diffs of the changes: (+23 -16) Index: llvm/lib/VMCore/AsmWriter.cpp diff -u llvm/lib/VMCore/AsmWriter.cpp:1.137 llvm/lib/VMCore/AsmWriter.cpp:1.138 --- llvm/lib/VMCore/AsmWriter.cpp:1.137 Wed Jun 9 10:26:53 2004 +++ llvm/lib/VMCore/AsmWriter.cpp Wed Jun 9 14:41:19 2004 @@ -74,7 +74,7 @@ /// Return the slot number of the specified value in it's type /// plane. Its an error to ask for something not in the SlotMachine. /// Its an error to ask for a Type* - unsigned getSlot(const Value *V, bool ignoreMissing = false ) ; + int getSlot(const Value *V); /// Determine if a Value has a slot or not bool hasSlot(const Value* V); @@ -525,12 +525,16 @@ } Machine = createSlotMachine(V); - if (Machine == 0) { Out << "BAD VALUE TYPE!"; return; } - - Slot = Machine->getSlot(V); + if (Machine == 0) + Slot = Machine->getSlot(V); + else + Slot = -1; delete Machine; } - Out << '%' << Slot; + if (Slot != -1) + Out << '%' << Slot; + else + Out << ""; } } } @@ -841,7 +845,12 @@ if (BB->hasName()) { // Print out the label if it exists... *Out << "\n" << BB->getName() << ':'; } else if (!BB->use_empty()) { // Don't print block # of no uses... - *Out << "\n;