From lattner at cs.uiuc.edu Mon Apr 12 00:16:11 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Apr 12 00:16:11 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/GCSE.cpp Message-ID: <200404120515.AAA27695@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: GCSE.cpp updated: 1.38 -> 1.39 --- Log message: Add support for removing invoke instructions --- Diffs of the changes: (+14 -0) Index: llvm/lib/Transforms/Scalar/GCSE.cpp diff -u llvm/lib/Transforms/Scalar/GCSE.cpp:1.38 llvm/lib/Transforms/Scalar/GCSE.cpp:1.39 --- llvm/lib/Transforms/Scalar/GCSE.cpp:1.38 Sat Apr 10 17:33:34 2004 +++ llvm/lib/Transforms/Scalar/GCSE.cpp Mon Apr 12 00:15:13 2004 @@ -167,6 +167,13 @@ // anything special. if (!isa(V)) { I->replaceAllUsesWith(V); + + if (InvokeInst *II = dyn_cast(I)) { + // Removing an invoke instruction requires adding a branch to the normal + // destination and removing PHI node entries in the exception destination. + new BranchInst(II->getNormalDest(), II); + II->getUnwindDest()->removePredecessor(II->getParent()); + } // Erase the instruction from the program. I->getParent()->getInstList().erase(I); @@ -178,6 +185,13 @@ // Perform the replacement. I->replaceAllUsesWith(C); + + if (InvokeInst *II = dyn_cast(I)) { + // Removing an invoke instruction requires adding a branch to the normal + // destination and removing PHI node entries in the exception destination. + new BranchInst(II->getNormalDest(), II); + II->getUnwindDest()->removePredecessor(II->getParent()); + } // Erase the instruction from the program. I->getParent()->getInstList().erase(I); From lattner at cs.uiuc.edu Mon Apr 12 00:17:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Apr 12 00:17:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/BasicAliasAnalysis.cpp Message-ID: <200404120516.AAA28188@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: BasicAliasAnalysis.cpp updated: 1.39 -> 1.40 --- Log message: Hrm, operator new and new[] do not belong here. We should not CSE them! :) --- Diffs of the changes: (+0 -3) Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp diff -u llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.39 llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.40 --- llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.39 Sun Apr 11 13:16:34 2004 +++ llvm/lib/Analysis/BasicAliasAnalysis.cpp Mon Apr 12 00:16:42 2004 @@ -646,9 +646,6 @@ // glibc functions: "__fpclassify", "__fpclassifyf", "__fpclassifyl", "__signbit", "__signbitf", "__signbitl", - - // C++ operator new/operator new[] - "_Znwj", "_Znaj", }; static const unsigned DAMTableSize = From lattner at cs.uiuc.edu Mon Apr 12 00:37:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Apr 12 00:37:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/CallGraph.h Message-ID: <200404120536.AAA29845@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: CallGraph.h updated: 1.33 -> 1.34 --- Log message: Change the call graph class to have TWO external nodes, making call graph SCC passes much more useful. In particular, this should fix the incredibly stupid missed inlining opportunities that the inliner suffered from. --- Diffs of the changes: (+35 -24) Index: llvm/include/llvm/Analysis/CallGraph.h diff -u llvm/include/llvm/Analysis/CallGraph.h:1.33 llvm/include/llvm/Analysis/CallGraph.h:1.34 --- llvm/include/llvm/Analysis/CallGraph.h:1.33 Tue Nov 11 16:41:30 2003 +++ llvm/include/llvm/Analysis/CallGraph.h Mon Apr 12 00:36:22 2004 @@ -14,17 +14,20 @@ // callgraph node keeps track of which functions the are called by the function // corresponding to the node. // -// A call graph will contain nodes where the function that they correspond to is -// null. This 'external' node is used to represent control flow that is not -// represented (or analyzable) in the module. As such, the external node will -// have edges to functions with the following properties: -// 1. All functions in the module without internal linkage, since they could -// be called by functions outside of the our analysis capability. +// A call graph may contain nodes where the function that they correspond to is +// null. These 'external' nodes are used to represent control flow that is not +// represented (or analyzable) in the module. In particular, this analysis +// builds one external node such that: +// 1. All functions in the module without internal linkage will have edges +// from this external node, indicating that they could be called by +// functions outside of the module. // 2. All functions whose address is used for something more than a direct -// call, for example being stored into a memory location. Since they may -// be called by an unknown caller later, they must be tracked as such. +// call, for example being stored into a memory location will also have an +// edge from this external node. Since they may be called by an unknown +// caller later, they must be tracked as such. // -// Similarly, functions have a call edge to the external node iff: +// There is a second external node added for calls that leave this module. +// Functions have a call edge to the external node iff: // 1. The function is external, reflecting the fact that they could call // anything without internal linkage or that has its address taken. // 2. The function contains an indirect function call. @@ -68,9 +71,18 @@ FunctionMapTy FunctionMap; // Map from a function to its node // Root is root of the call graph, or the external node if a 'main' function - // couldn't be found. ExternalNode is equivalent to (*this)[0]. + // couldn't be found. // - CallGraphNode *Root, *ExternalNode; + CallGraphNode *Root; + + // ExternalCallingNode - This node has edges to all external functions and + // those internal functions that have their address taken. + CallGraphNode *ExternalCallingNode; + + // CallsExternalNode - This node has edges to it from all functions making + // indirect calls or calling an external function. + CallGraphNode *CallsExternalNode; + public: //===--------------------------------------------------------------------- @@ -79,11 +91,8 @@ typedef FunctionMapTy::iterator iterator; typedef FunctionMapTy::const_iterator const_iterator; - // getExternalNode - Return the node that points to all functions that are - // accessable from outside of the current program. - // - CallGraphNode *getExternalNode() { return ExternalNode; } - const CallGraphNode *getExternalNode() const { return ExternalNode; } + CallGraphNode *getExternalCallingNode() const { return ExternalCallingNode; } + CallGraphNode *getCallsExternalNode() const { return CallsExternalNode; } // getRoot - Return the root of the call graph, which is either main, or if // main cannot be found, the external node. @@ -215,17 +224,19 @@ CalledFunctions.clear(); } -private: // Stuff to construct the node, used by CallGraph - friend class CallGraph; - - // CallGraphNode ctor - Create a node for the specified function... - inline CallGraphNode(Function *f) : F(f) {} - // addCalledFunction add a function to the list of functions called by this // one void addCalledFunction(CallGraphNode *M) { CalledFunctions.push_back(M); } + + void removeCallEdgeTo(CallGraphNode *Callee); + +private: // Stuff to construct the node, used by CallGraph + friend class CallGraph; + + // CallGraphNode ctor - Create a node for the specified function... + inline CallGraphNode(Function *f) : F(f) {} }; @@ -257,7 +268,7 @@ template<> struct GraphTraits : public GraphTraits { static NodeType *getEntryNode(CallGraph *CGN) { - return CGN->getExternalNode(); // Start at the external node! + return CGN->getExternalCallingNode(); // Start at the external node! } typedef std::pair PairTy; typedef std::pointer_to_unary_function DerefFun; @@ -279,7 +290,7 @@ template<> struct GraphTraits : public GraphTraits { static NodeType *getEntryNode(const CallGraph *CGN) { - return CGN->getExternalNode(); + return CGN->getExternalCallingNode(); } // nodes_iterator/begin/end - Allow iteration over all nodes in the graph typedef CallGraph::const_iterator nodes_iterator; From lattner at cs.uiuc.edu Mon Apr 12 00:37:04 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Apr 12 00:37:04 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/CallGraph.cpp Message-ID: <200404120536.AAA29858@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: CallGraph.cpp updated: 1.34 -> 1.35 --- Log message: Change the call graph class to have TWO external nodes, making call graph SCC passes much more useful. In particular, this should fix the incredibly stupid missed inlining opportunities that the inliner suffered from. --- Diffs of the changes: (+22 -181) Index: llvm/lib/Analysis/IPA/CallGraph.cpp diff -u llvm/lib/Analysis/IPA/CallGraph.cpp:1.34 llvm/lib/Analysis/IPA/CallGraph.cpp:1.35 --- llvm/lib/Analysis/IPA/CallGraph.cpp:1.34 Tue Nov 11 16:41:32 2003 +++ llvm/lib/Analysis/IPA/CallGraph.cpp Mon Apr 12 00:36:32 2004 @@ -7,41 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This interface is used to build and manipulate a call graph, which is a very -// useful tool for interprocedural optimization. -// -// Every function in a module is represented as a node in the call graph. The -// callgraph node keeps track of which functions the are called by the function -// corresponding to the node. -// -// A call graph will contain nodes where the function that they correspond to is -// null. This 'external' node is used to represent control flow that is not -// represented (or analyzable) in the module. As such, the external node will -// have edges to functions with the following properties: -// 1. All functions in the module without internal linkage, since they could -// be called by functions outside of the our analysis capability. -// 2. All functions whose address is used for something more than a direct -// call, for example being stored into a memory location. Since they may -// be called by an unknown caller later, they must be tracked as such. -// -// Similarly, functions have a call edge to the external node iff: -// 1. The function is external, reflecting the fact that they could call -// anything without internal linkage or that has its address taken. -// 2. The function contains an indirect function call. -// -// As an extension in the future, there may be multiple nodes with a null -// function. These will be used when we can prove (through pointer analysis) -// that an indirect call site can call only a specific set of functions. -// -// Because of these properties, the CallGraph captures a conservative superset -// of all of the caller-callee relationships, which is useful for -// transformations. -// -// The CallGraph class also attempts to figure out what the root of the -// CallGraph is, which is currently does by looking for a function named 'main'. -// If no function named 'main' is found, the external node is used as the entry -// node, reflecting the fact that any function without internal linkage could -// be called into (which is common for libraries). +// This file implements the CallGraph class. // //===----------------------------------------------------------------------===// @@ -52,143 +18,10 @@ #include "llvm/iTerminators.h" #include "llvm/Support/CallSite.h" #include "Support/STLExtras.h" - -namespace llvm { +using namespace llvm; static RegisterAnalysis X("callgraph", "Call Graph Construction"); -static const char * const KnownExternalFunctions[] = { - // Low-level system calls - "open", - "read", - "write", - "writev", - "lseek", - "poll", - "ioctl", - - // Low-level stdc library functions - "abort", "exit", - "getenv", "putenv", - - // Standard IO functions - "printf", - "sprintf", - "fopen", - "freopen", - "fclose", - "fwrite", - "puts", - "fputs", - "getc", - "ungetc", - "putc", - "putchar", - "fread", - "fileno", - "ftell", - "fflush", - "fseek", - "fileno", - "ferror", - "feof", - "fdopen", - "__fxstat", - "setbuf", - "setbuffer", - "etlinebuf", - "setvbuf", - - // Memory functions - "malloc", - "free", - "realloc", - "calloc", - "memalign", - - // String functions - "atoi", - "memmove", - "memset", - "memchr", - "memcmp", - "strchr", - "strncpy", - "strncmp", - "strcmp", - "strtok", - "__strcoll_l", - "__strxfrm_l", - "__strftime_l", - "__strtol_l", - "__strtoul_l", - "__strtoll_l", - "__strtoull_l", - "__strtof_l", - "__strtod_l", - "__strtold_l", - "isalpha", - - // Math functions - "exp", "sqrt", "cbrt", "hypot", - "log", "log10", "pow", - "sin", "cos", "tan", - "asin", "acos", "atan", "atan2", - - // Locale functions - "__uselocale", - "__newlocale", - "__freelocale", - "__duplocale", - "__nl_langinfo_l", - - // gettext functions used by libstdc++ - "gettext", - "dgettext", - "dcgettext", - "textdomain", - "bindtextdomain", - - // Random stuff - "__assert_fail", - "__errno_location", - "clock", "time", - "__main", -}; - - -/// ExternalFunctionDoesntCallIntoProgram - This hack is used to indicate to the -/// call graph that the specified external function is _KNOWN_ to not call back -/// into the program. This is important, because otherwise functions which call -/// "printf" for example, end up in a great big SCC that goes from the function -/// through main. -/// -static bool ExternalFunctionDoesntCallIntoProgram(const std::string &Name) { - static std::vector Funcs; - - // First time this is called? - if (Funcs.empty()) { - // Add a whole bunch of functions which are often used... - Funcs.insert(Funcs.end(), KnownExternalFunctions, - KnownExternalFunctions+ - sizeof(KnownExternalFunctions)/sizeof(KnownExternalFunctions[0])); - // Sort the list for efficient access - std::sort(Funcs.begin(), Funcs.end()); - } - - if (Name.size() > 7 && !memcmp("__llvm_", Name.c_str(), 7)) - return true; - - // Binary search for the function name... - std::vector::iterator I = - std::lower_bound(Funcs.begin(), Funcs.end(), Name); - - // Found it? - return I != Funcs.end() && *I == Name; -} - - - // getNodeFor - Return the node for the specified function or create one if it // does not already exist. // @@ -215,12 +48,12 @@ // If this function has external linkage, anything could call it... if (!F->hasInternalLinkage()) { - ExternalNode->addCalledFunction(Node); + ExternalCallingNode->addCalledFunction(Node); // Found the entry point? if (F->getName() == "main") { - if (Root) - Root = ExternalNode; // Found multiple external mains? Don't pick one. + if (Root) // Found multiple external mains? Don't pick one. + Root = ExternalCallingNode; else Root = Node; // Found a main, keep track of it! } @@ -228,9 +61,8 @@ // If this function is not defined in this translation unit, it could call // anything. - if (F->isExternal() && !F->getIntrinsicID() && - !ExternalFunctionDoesntCallIntoProgram(F->getName())) - Node->addCalledFunction(ExternalNode); + if (F->isExternal() && !F->getIntrinsicID()) + Node->addCalledFunction(CallsExternalNode); // Loop over all of the users of the function... looking for callers... // @@ -259,14 +91,14 @@ } } if (isUsedExternally) - ExternalNode->addCalledFunction(Node); + ExternalCallingNode->addCalledFunction(Node); // Look for an indirect function call... for (Function::iterator BB = F->begin(), BBE = F->end(); BB != BBE; ++BB) for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE; ++II){ CallSite CS = CallSite::get(II); if (CS.getInstruction() && !CS.getCalledFunction()) - Node->addCalledFunction(ExternalNode); + Node->addCalledFunction(CallsExternalNode); } } @@ -274,7 +106,8 @@ destroy(); Mod = &M; - ExternalNode = getNodeFor(0); + ExternalCallingNode = getNodeFor(0); + CallsExternalNode = new CallGraphNode(0); Root = 0; // Add every function to the call graph... @@ -282,7 +115,7 @@ addToCallGraph(I); // If we didn't find a main function, use the external call graph node - if (Root == 0) Root = ExternalNode; + if (Root == 0) Root = ExternalCallingNode; return false; } @@ -328,7 +161,7 @@ // Functions to keep a call graph up to date with a function that has been // modified // -void CallGraph::addFunctionToModule(Function *Meth) { +void CallGraph::addFunctionToModule(Function *F) { assert(0 && "not implemented"); abort(); } @@ -352,4 +185,12 @@ void CallGraph::stub() {} -} // End llvm namespace +void CallGraphNode::removeCallEdgeTo(CallGraphNode *Callee) { + for (unsigned i = CalledFunctions.size(); ; --i) { + assert(i && "Cannot find callee to remove!"); + if (CalledFunctions[i-1] == Callee) { + CalledFunctions.erase(CalledFunctions.begin()+i-1); + return; + } + } +} From lattner at cs.uiuc.edu Mon Apr 12 00:38:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Apr 12 00:38:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/Inliner.cpp Message-ID: <200404120537.AAA30010@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: Inliner.cpp updated: 1.8 -> 1.9 --- Log message: Actually update the call graph as the inliner changes it. This allows us to execute other CallGraphSCCPasses after the inliner without crashing. --- Diffs of the changes: (+20 -1) Index: llvm/lib/Transforms/IPO/Inliner.cpp diff -u llvm/lib/Transforms/IPO/Inliner.cpp:1.8 llvm/lib/Transforms/IPO/Inliner.cpp:1.9 --- llvm/lib/Transforms/IPO/Inliner.cpp:1.8 Sun Apr 11 23:06:56 2004 +++ llvm/lib/Transforms/IPO/Inliner.cpp Mon Apr 12 00:37:29 2004 @@ -93,7 +93,21 @@ // Attempt to inline the function... if (InlineFunction(CS)) { ++NumInlined; + + // Update the call graph by deleting the edge from Callee to Caller + CallGraphNode *CalleeNode = CG[Callee]; + CallGraphNode *CallerNode = CG[Caller]; + CallerNode->removeCallEdgeTo(CalleeNode); + + // Since we inlined all uninlinable call sites in the callee into the + // caller, add edges from the caller to all of the callees of the + // callee. + for (CallGraphNode::iterator I = CalleeNode->begin(), + E = CalleeNode->end(); I != E; ++I) + CallerNode->addCalledFunction(*I); + // If the only remaining use of the function is a dead constant + // pointer ref, remove it. if (Callee->hasOneUse()) if (ConstantPointerRef *CPR = dyn_cast(Callee->use_back())) @@ -110,7 +124,12 @@ if (I != SCCFunctions.end()) // Remove function from this SCC. SCCFunctions.erase(I); - Callee->getParent()->getFunctionList().erase(Callee); + // Remove any call graph edges from the callee to its callees. + while (CalleeNode->begin() != CalleeNode->end()) + CalleeNode->removeCallEdgeTo(*(CalleeNode->end()-1)); + + // Removing the node for callee from the call graph and delete it. + delete CG.removeFunctionFromModule(CalleeNode); ++NumDeleted; } Changed = true; From lattner at cs.uiuc.edu Mon Apr 12 00:38:04 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Apr 12 00:38:04 2004 Subject: [llvm-commits] CVS: llvm/tools/analyze/GraphPrinters.cpp Message-ID: <200404120538.AAA30042@zion.cs.uiuc.edu> Changes in directory llvm/tools/analyze: GraphPrinters.cpp updated: 1.6 -> 1.7 --- Log message: finegrainify namespacification --- Diffs of the changes: (+16 -17) Index: llvm/tools/analyze/GraphPrinters.cpp diff -u llvm/tools/analyze/GraphPrinters.cpp:1.6 llvm/tools/analyze/GraphPrinters.cpp:1.7 --- llvm/tools/analyze/GraphPrinters.cpp:1.6 Tue Nov 11 16:41:34 2003 +++ llvm/tools/analyze/GraphPrinters.cpp Mon Apr 12 00:38:01 2004 @@ -19,8 +19,7 @@ #include "llvm/Value.h" #include "llvm/Analysis/CallGraph.h" #include - -namespace llvm { +using namespace llvm; template static void WriteGraphToFile(std::ostream &O, const std::string &GraphName, @@ -41,19 +40,21 @@ // Call Graph Printer //===----------------------------------------------------------------------===// -template<> -struct DOTGraphTraits : public DefaultDOTGraphTraits { - static std::string getGraphName(CallGraph *F) { - return "Call Graph"; - } - - static std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) { - if (Node->getFunction()) - return ((Value*)Node->getFunction())->getName(); - else - return "Indirect call node"; - } -}; +namespace llvm { + template<> + struct DOTGraphTraits : public DefaultDOTGraphTraits { + static std::string getGraphName(CallGraph *F) { + return "Call Graph"; + } + + static std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) { + if (Node->getFunction()) + return ((Value*)Node->getFunction())->getName(); + else + return "Indirect call node"; + } + }; +} namespace { @@ -74,5 +75,3 @@ RegisterAnalysis P2("print-callgraph", "Print Call Graph to 'dot' file"); }; - -} // End llvm namespace From lattner at cs.uiuc.edu Mon Apr 12 00:39:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Apr 12 00:39:01 2004 Subject: [llvm-commits] CVS: llvm/tools/gccld/GenerateCode.cpp Message-ID: <200404120538.AAA30051@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: GenerateCode.cpp updated: 1.26 -> 1.27 --- Log message: Add a couple more IPO's --- Diffs of the changes: (+3 -0) Index: llvm/tools/gccld/GenerateCode.cpp diff -u llvm/tools/gccld/GenerateCode.cpp:1.26 llvm/tools/gccld/GenerateCode.cpp:1.27 --- llvm/tools/gccld/GenerateCode.cpp:1.26 Thu Apr 8 10:18:59 2004 +++ llvm/tools/gccld/GenerateCode.cpp Mon Apr 12 00:38:15 2004 @@ -105,6 +105,9 @@ if (!DisableInline) addPass(Passes, createFunctionInliningPass()); // Inline small functions + addPass(Passes, createPruneEHPass()); // Remove dead EH info + addPass(Passes, createGlobalDCEPass()); // Remove dead functions + // If we didn't decide to inline a function, check to see if we can // transform it to pass arguments by value instead of by reference. addPass(Passes, createArgumentPromotionPass()); From criswell at cs.uiuc.edu Mon Apr 12 10:03:03 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Apr 12 10:03:03 2004 Subject: [llvm-commits] CVS: llvm/docs/LangRef.html Message-ID: <200404121502.KAA22281@choi.cs.uiuc.edu> Changes in directory llvm/docs: LangRef.html updated: 1.58 -> 1.59 --- Log message: Added initial design for the llvm.readio and llvm.writeio intrinsics. --- Diffs of the changes: (+97 -1) Index: llvm/docs/LangRef.html diff -u llvm/docs/LangRef.html:1.58 llvm/docs/LangRef.html:1.59 --- llvm/docs/LangRef.html:1.58 Fri Apr 9 11:48:45 2004 +++ llvm/docs/LangRef.html Mon Apr 12 10:02:16 2004 @@ -107,6 +107,8 @@
  1. 'llvm.readport' Intrinsic
  2. 'llvm.writeport' Intrinsic
  3. +
  4. 'llvm.readio' Intrinsic
  5. +
  6. 'llvm.writeio' Intrinsic
  • Standard C Library Intrinsics
      @@ -2013,6 +2015,7 @@

      +
      'llvm.readport' Intrinsic @@ -2095,6 +2098,99 @@
      + + + +
      + +
      Syntax:
      +
      +  call <integer type> (<integer type>)* %llvm.readio (<integer type> <address>)
      +
      + +
      Overview:
      + +

      +The 'llvm.readio' intrinsic reads data from a memory mapped I/O +address. +

      + +
      Arguments:
      + +

      +The argument to this intrinsic indicates the memory address from which to read +the data. +

      + +
      Semantics:
      + +

      +The 'llvm.readio' intrinsic reads data from a memory mapped I/O +location specified by address and returns the value. The address and +return value must be integers, but the size allowed for each is dependent upon +the platform upon which the program is code generated. +

      + +

      +This intrinsic ensures that the I/O data read occurs in instruction order in +relation to other I/O data reads and writes (as opposed to a normal load, where +hardware scheduling can re-arrange the actual memory accesses to occur out of +order). +

      + +
      + + + + +
      + +
      Syntax:
      +
      +  call void (<integer type>, <integer type>)* %llvm.writeio (<integer type> <value>, <integer type> <address>)
      +
      + +
      Overview:
      + +

      +The 'llvm.writeio' intrinsic writes data to the specified memory +mapped I/O address. +

      + +
      Arguments:
      + +

      +The first argument to this intrinsic indicates the memory address to which data +should be written. +

      + +

      +The second argument is the value to write to the memory mapped I/O location. +

      + +
      Semantics:
      + +

      +The 'llvm.writeio' intrinsic writes value to the memory mapped +I/O address specified by address. The address and value must be +integers, but the size is dependent upon the platform upon which the program is +code generated. +

      + +

      +This intrinsic ensures that the I/O data write occurs in instruction order in +relation to other I/O data reads and writes (as opposed to a normal store, +where hardware scheduling can re-arrange the actual memory accesses to occur +out of order). +

      + +
      + +
      Standard C Library Intrinsics @@ -2291,7 +2387,7 @@ Chris Lattner
      The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/04/09 16:48:45 $ + Last modified: $Date: 2004/04/12 15:02:16 $ From alkis at cs.uiuc.edu Mon Apr 12 10:41:03 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon Apr 12 10:41:03 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/Generic/2004-04-09-SameValueCoalescing.llx Message-ID: <200404121540.KAA19149@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/Generic: 2004-04-09-SameValueCoalescing.llx added (r1.1) --- Log message: Add same value coalescing testcase --- Diffs of the changes: (+19 -0) Index: llvm/test/Regression/CodeGen/Generic/2004-04-09-SameValueCoalescing.llx diff -c /dev/null llvm/test/Regression/CodeGen/Generic/2004-04-09-SameValueCoalescing.llx:1.1 *** /dev/null Mon Apr 12 10:40:42 2004 --- llvm/test/Regression/CodeGen/Generic/2004-04-09-SameValueCoalescing.llx Mon Apr 12 10:40:25 2004 *************** *** 0 **** --- 1,19 ---- + ; Linear scan does not currently coalesce any two variables that have + ; overlapping live intervals. When two overlapping intervals have the same + ; value, they can be joined though. + ; + ; RUN: llvm-as < %s | llc -march=x86 -regalloc=linearscan | not grep 'mov %[A-Z]\{2,3\}, %[A-Z]\{2,3\}' + + int %main() { + %ptr = alloca uint + br label %Loop + Loop: + %I = phi int [0, %0], [%i2, %Loop] + %i2 = add int %I, 1 + %i3 = cast int %i2 to uint + store uint %i3, uint* %ptr + %C = seteq int %i2, 10 + br bool %C, label %Out, label %Loop + Out: + ret int 0 + } From alkis at cs.uiuc.edu Mon Apr 12 10:58:02 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon Apr 12 10:58:02 2004 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervals.cpp Message-ID: <200404121558.KAA31660@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervals.cpp updated: 1.67 -> 1.68 --- Log message: Print def lists a bit more compactly --- Diffs of the changes: (+1 -1) Index: llvm/lib/CodeGen/LiveIntervals.cpp diff -u llvm/lib/CodeGen/LiveIntervals.cpp:1.67 llvm/lib/CodeGen/LiveIntervals.cpp:1.68 --- llvm/lib/CodeGen/LiveIntervals.cpp:1.67 Fri Apr 9 13:07:57 2004 +++ llvm/lib/CodeGen/LiveIntervals.cpp Mon Apr 12 10:57:58 2004 @@ -713,7 +713,7 @@ os << " {" << li.defs.front(); for (LiveIntervals::Interval::Defs::const_iterator i = next(li.defs.begin()), e = li.defs.end(); i != e; ++i) - os << ", " << *i; + os << "," << *i; os << "}"; os << " = "; From criswell at cs.uiuc.edu Mon Apr 12 11:34:01 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Apr 12 11:34:01 2004 Subject: [llvm-commits] CVS: llvm/docs/LangRef.html Message-ID: <200404121633.LAA22370@choi.cs.uiuc.edu> Changes in directory llvm/docs: LangRef.html updated: 1.59 -> 1.60 --- Log message: Corrected the descriptions of the llvm.writeport and llvm.writeio intrinsics. Modified llvm.readio and llvm.writeio to use pointers to memory instead of integers. This should take care of problems such as different pointer sizes, casting integers to pointers, weird architectural pointer types, etc. Re-worded the description of llvm.readio and llvm.writeio so that it should be more clear as to why they should be used over regular loads/stores for I/O. --- Diffs of the changes: (+32 -29) Index: llvm/docs/LangRef.html diff -u llvm/docs/LangRef.html:1.59 llvm/docs/LangRef.html:1.60 --- llvm/docs/LangRef.html:1.59 Mon Apr 12 10:02:16 2004 +++ llvm/docs/LangRef.html Mon Apr 12 11:33:19 2004 @@ -2077,13 +2077,13 @@
      Arguments:

      -The first argument to this intrinsic indicates the hardware I/O address to -which data should be written. The address is in the hardware I/O address -namespace (as opposed to being a memory location for memory mapped I/O). +The first argument is the value to write to the I/O port.

      -The second argument is the value to write to the I/O port. +The second argument indicates the hardware I/O address to which data should be +written. The address is in the hardware I/O address namespace (as opposed to +being a memory location for memory mapped I/O).

      Semantics:
      @@ -2107,7 +2107,7 @@
      Syntax:
      -  call <integer type> (<integer type>)* %llvm.readio (<integer type> <address>)
      +  call <result> (<ty>*)* %llvm.readio (<ty> * <pointer>)
       
      Overview:
      @@ -2120,24 +2120,28 @@
      Arguments:

      -The argument to this intrinsic indicates the memory address from which to read -the data. +The argument to this intrinsic is a pointer indicating the memory address from +which to read the data. The data must be a +first class type.

      Semantics:

      The 'llvm.readio' intrinsic reads data from a memory mapped I/O -location specified by address and returns the value. The address and -return value must be integers, but the size allowed for each is dependent upon -the platform upon which the program is code generated. +location specified by pointer and returns the value. The argument must +be a pointer, and the return value must be a +first class type. However, certain architectures +may not support I/O on all first class types. For example, 32 bit processors +may only support I/O on data types that are 32 bits or less.

      -This intrinsic ensures that the I/O data read occurs in instruction order in -relation to other I/O data reads and writes (as opposed to a normal load, where -hardware scheduling can re-arrange the actual memory accesses to occur out of -order). +This intrinsic enforces an in-order memory model for llvm.readio and +llvm.writeio calls on machines that use dynamic scheduling. Dynamically +scheduled processors may execute loads and stores out of order, re-ordering at +run time accesses to memory mapped I/O registers. Using these intrinsics +ensures that accesses to memory mapped I/O registers occur in program order.

      @@ -2151,7 +2155,7 @@
      Syntax:
      -  call void (<integer type>, <integer type>)* %llvm.writeio (<integer type> <value>, <integer type> <address>)
      +  call void (<ty1>, <ty2>*)* %llvm.writeio (<ty1> <value>, <ty2> * <pointer>)
       
      Overview:
      @@ -2164,28 +2168,27 @@
      Arguments:

      -The first argument to this intrinsic indicates the memory address to which data -should be written. -

      - -

      -The second argument is the value to write to the memory mapped I/O location. +The first argument is the value to write to the memory mapped I/O location. +The second argument is a pointer indicating the memory address to which the +data should be written.

      Semantics:

      The 'llvm.writeio' intrinsic writes value to the memory mapped -I/O address specified by address. The address and value must be -integers, but the size is dependent upon the platform upon which the program is -code generated. +I/O address specified by pointer. The value must be a +first class type. However, certain architectures +may not support I/O on all first class types. For example, 32 bit processors +may only support I/O on data types that are 32 bits or less.

      -This intrinsic ensures that the I/O data write occurs in instruction order in -relation to other I/O data reads and writes (as opposed to a normal store, -where hardware scheduling can re-arrange the actual memory accesses to occur -out of order). +This intrinsic enforces an in-order memory model for llvm.readio and +llvm.writeio calls on machines that use dynamic scheduling. Dynamically +scheduled processors may execute loads and stores out of order, re-ordering at +run time accesses to memory mapped I/O registers. Using these intrinsics +ensures that accesses to memory mapped I/O registers occur in program order.

      @@ -2387,7 +2390,7 @@ Chris Lattner
      The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/04/12 15:02:16 $ + Last modified: $Date: 2004/04/12 16:33:19 $ From criswell at cs.uiuc.edu Mon Apr 12 11:44:01 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Mon Apr 12 11:44:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/ioport.llx Message-ID: <200404121642.LAA24538@choi.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: ioport.llx added (r1.1) --- Log message: Added testcase for the llvm.readport and llvm.writeport intrinsics. --- Diffs of the changes: (+18 -0) Index: llvm/test/Regression/CodeGen/X86/ioport.llx diff -c /dev/null llvm/test/Regression/CodeGen/X86/ioport.llx:1.1 *** /dev/null Mon Apr 12 11:42:56 2004 --- llvm/test/Regression/CodeGen/X86/ioport.llx Mon Apr 12 11:42:43 2004 *************** *** 0 **** --- 1,18 ---- + ; RUN: llvm-as < %s | llc -march=x86 + + implementation + + declare int %llvm.readport (ushort) + declare void %llvm.writeport (int, ushort) + + uint %in (uint %p) { + %i1 = call int(ushort)* %llvm.readport (ushort 255) + ret uint 5 + } + + + uint %out (uint %p) { + call void(int, ushort)* %llvm.writeport (int 1, ushort 255) + ret uint 5 + } + From alkis at cs.uiuc.edu Mon Apr 12 12:40:02 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon Apr 12 12:40:02 2004 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervals.cpp Message-ID: <200404121739.MAA26529@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervals.cpp updated: 1.68 -> 1.69 --- Log message: Correctly compute spill weights --- Diffs of the changes: (+19 -18) Index: llvm/lib/CodeGen/LiveIntervals.cpp diff -u llvm/lib/CodeGen/LiveIntervals.cpp:1.68 llvm/lib/CodeGen/LiveIntervals.cpp:1.69 --- llvm/lib/CodeGen/LiveIntervals.cpp:1.68 Mon Apr 12 10:57:58 2004 +++ llvm/lib/CodeGen/LiveIntervals.cpp Mon Apr 12 12:39:20 2004 @@ -133,24 +133,10 @@ for (MachineBasicBlock::iterator mii = mbb->begin(), mie = mbb->end(); mii != mie; ) { - for (unsigned i = 0; i < mii->getNumOperands(); ++i) { - const MachineOperand& mop = mii->getOperand(i); - if (mop.isRegister() && mop.getReg()) { - // replace register with representative register - unsigned reg = rep(mop.getReg()); - mii->SetMachineOperandReg(i, reg); - - if (MRegisterInfo::isVirtualRegister(reg)) { - Reg2IntervalMap::iterator r2iit = r2iMap_.find(reg); - assert(r2iit != r2iMap_.end()); - r2iit->second->weight += pow(10.0F, loopDepth); - } - } - } - - // if the move is now an identity move delete it + // if the move will be an identity move delete it unsigned srcReg, dstReg; - if (tii.isMoveInstr(*mii, srcReg, dstReg) && srcReg == dstReg) { + if (tii.isMoveInstr(*mii, srcReg, dstReg) && + rep(srcReg) == rep(dstReg)) { // remove from def list Interval& interval = getOrCreateInterval(dstReg); unsigned defIndex = getInstructionIndex(mii); @@ -168,8 +154,23 @@ mii = mbbi->erase(mii); ++numPeep; } - else + else { + for (unsigned i = 0; i < mii->getNumOperands(); ++i) { + const MachineOperand& mop = mii->getOperand(i); + if (mop.isRegister() && mop.getReg() && + MRegisterInfo::isVirtualRegister(mop.getReg())) { + // replace register with representative register + unsigned reg = rep(mop.getReg()); + mii->SetMachineOperandReg(i, reg); + + Reg2IntervalMap::iterator r2iit = r2iMap_.find(reg); + assert(r2iit != r2iMap_.end()); + r2iit->second->weight += + (mop.isUse() + mop.isDef()) * pow(10.0F, loopDepth); + } + } ++mii; + } } } From alkis at cs.uiuc.edu Mon Apr 12 14:05:02 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon Apr 12 14:05:02 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/Generic/2004-04-09-SameValueCoalescing.llx Message-ID: <200404121904.OAA02618@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/Generic: 2004-04-09-SameValueCoalescing.llx updated: 1.1 -> 1.2 --- Log message: Update testcase to illustrate the coalescing problem. The previous one did not work because of a fix in the x86 instruction selector. --- Diffs of the changes: (+4 -12) Index: llvm/test/Regression/CodeGen/Generic/2004-04-09-SameValueCoalescing.llx diff -u llvm/test/Regression/CodeGen/Generic/2004-04-09-SameValueCoalescing.llx:1.1 llvm/test/Regression/CodeGen/Generic/2004-04-09-SameValueCoalescing.llx:1.2 --- llvm/test/Regression/CodeGen/Generic/2004-04-09-SameValueCoalescing.llx:1.1 Mon Apr 12 10:40:25 2004 +++ llvm/test/Regression/CodeGen/Generic/2004-04-09-SameValueCoalescing.llx Mon Apr 12 14:04:22 2004 @@ -4,16 +4,8 @@ ; ; RUN: llvm-as < %s | llc -march=x86 -regalloc=linearscan | not grep 'mov %[A-Z]\{2,3\}, %[A-Z]\{2,3\}' -int %main() { - %ptr = alloca uint - br label %Loop -Loop: - %I = phi int [0, %0], [%i2, %Loop] - %i2 = add int %I, 1 - %i3 = cast int %i2 to uint - store uint %i3, uint* %ptr - %C = seteq int %i2, 10 - br bool %C, label %Out, label %Loop -Out: - ret int 0 +long %test(long %x) { +entry: + %tmp.1 = mul long %x, 4294967297 ; [#uses=1] + ret long %tmp.1 } From lattner at cs.uiuc.edu Mon Apr 12 15:27:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Apr 12 15:27:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/LoopInfo.h Message-ID: <200404122026.PAA25835@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: LoopInfo.h updated: 1.31 -> 1.32 --- Log message: Add some methods that are useful for updating loop information. --- Diffs of the changes: (+48 -2) Index: llvm/include/llvm/Analysis/LoopInfo.h diff -u llvm/include/llvm/Analysis/LoopInfo.h:1.31 llvm/include/llvm/Analysis/LoopInfo.h:1.32 --- llvm/include/llvm/Analysis/LoopInfo.h:1.31 Fri Jan 30 11:22:50 2004 +++ llvm/include/llvm/Analysis/LoopInfo.h Mon Apr 12 15:26:11 2004 @@ -9,7 +9,7 @@ // // This file defines the LoopInfo class that is used to identify natural loops // and determine the loop depth of various nodes of the CFG. Note that natural -// loops may actually be several loops that share the same header node... +// loops may actually be several loops that share the same header node. // // This analysis calculates the nesting structure of loops in a function. For // each natural loop identified, this analysis identifies natural loops @@ -48,6 +48,9 @@ Loop(const Loop &); // DO NOT IMPLEMENT const Loop &operator=(const Loop &); // DO NOT IMPLEMENT public: + /// Loop ctor - This creates an empty loop. + Loop() : ParentLoop(0), LoopDepth(0) { + } unsigned getLoopDepth() const { return LoopDepth; } BasicBlock *getHeader() const { return Blocks.front(); } @@ -117,11 +120,45 @@ /// void changeExitBlock(BasicBlock *Old, BasicBlock *New); + /// replaceChildLoopWith - This is used when splitting loops up. It replaces + /// the OldChild entry in our children list with NewChild, and updates the + /// parent pointer of OldChild to be null and the NewChild to be this loop. + /// This updates the loop depth of the new child. + void replaceChildLoopWith(Loop *OldChild, Loop *NewChild); + + /// addChildLoop - Add the specified loop to be a child of this loop. This + /// updates the loop depth of the new child. + /// + void addChildLoop(Loop *NewChild); + + /// removeChildLoop - This removes the specified child from being a subloop of + /// this loop. The loop is not deleted, as it will presumably be inserted + /// into another loop. + Loop *removeChildLoop(iterator OldChild); + + /// addExitBlock - Add the specified exit block to the loop. + /// + void addExitBlock(BasicBlock *BB) { + ExitBlocks.push_back(BB); + } + + /// addBlockEntry - This adds a basic block directly to the basic block list. + /// This should only be used by transformations that create new loops. Other + /// transformations should use addBasicBlockToLoop. + void addBlockEntry(BasicBlock *BB) { + Blocks.push_back(BB); + } + + /// removeBlockFromLoop - This removes the specified basic block from the + /// current loop, updating the Blocks and ExitBlocks lists as appropriate. + /// This does not update the mapping in the LoopInfo class. + void removeBlockFromLoop(BasicBlock *BB); + void print(std::ostream &O, unsigned Depth = 0) const; void dump() const; private: friend class LoopInfo; - inline Loop(BasicBlock *BB) : ParentLoop(0) { + Loop(BasicBlock *BB) : ParentLoop(0) { Blocks.push_back(BB); LoopDepth = 0; } ~Loop() { @@ -193,6 +230,15 @@ /// getAnalysisUsage - Requires dominator sets /// virtual void getAnalysisUsage(AnalysisUsage &AU) const; + + /// changeLoopFor - Change the top-level loop that contains BB to the + /// specified loop. This should be used by transformations that restructure + /// the loop hierarchy tree. + void changeLoopFor(BasicBlock *BB, Loop *L); + + /// changeTopLevelLoop - Replace the specified loop in the top-level loops + /// list with the indicated loop. + void changeTopLevelLoop(Loop *OldLoop, Loop *NewLoop); static void stub(); // Noop private: From lattner at cs.uiuc.edu Mon Apr 12 15:27:09 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Apr 12 15:27:09 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/LoopInfo.cpp Message-ID: <200404122026.PAA25868@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: LoopInfo.cpp updated: 1.47 -> 1.48 --- Log message: Add some methods that are useful for updating loop information. --- Diffs of the changes: (+87 -5) Index: llvm/lib/Analysis/LoopInfo.cpp diff -u llvm/lib/Analysis/LoopInfo.cpp:1.47 llvm/lib/Analysis/LoopInfo.cpp:1.48 --- llvm/lib/Analysis/LoopInfo.cpp:1.47 Fri Jan 30 11:26:24 2004 +++ llvm/lib/Analysis/LoopInfo.cpp Mon Apr 12 15:26:17 2004 @@ -20,8 +20,7 @@ #include "llvm/Support/CFG.h" #include "Support/DepthFirstIterator.h" #include - -namespace llvm { +using namespace llvm; static RegisterAnalysis X("loops", "Natural Loop Construction", true); @@ -294,7 +293,25 @@ L->ParentLoop = Parent; } - +/// changeLoopFor - Change the top-level loop that contains BB to the +/// specified loop. This should be used by transformations that restructure +/// the loop hierarchy tree. +void LoopInfo::changeLoopFor(BasicBlock *BB, Loop *L) { + Loop *&OldLoop = BBMap[BB]; + assert(OldLoop && "Block not in a loop yet!"); + OldLoop = L; +} + +/// changeTopLevelLoop - Replace the specified loop in the top-level loops +/// list with the indicated loop. +void LoopInfo::changeTopLevelLoop(Loop *OldLoop, Loop *NewLoop) { + std::vector::iterator I = std::find(TopLevelLoops.begin(), + TopLevelLoops.end(), OldLoop); + assert(I != TopLevelLoops.end() && "Old loop not at top level!"); + *I = NewLoop; + assert(NewLoop->ParentLoop == 0 && OldLoop->ParentLoop == 0 && + "Loops already embedded into a subloop!"); +} /// getLoopPreheader - If there is a preheader for this loop, return it. A /// loop has a preheader if there is only one edge to the header of the loop @@ -339,7 +356,8 @@ /// valid to replace the loop header with this method. /// void Loop::addBasicBlockToLoop(BasicBlock *NewBB, LoopInfo &LI) { - assert(LI[getHeader()] == this && "Incorrect LI specified for this loop!"); + assert((Blocks.empty() || LI[getHeader()] == this) && + "Incorrect LI specified for this loop!"); assert(NewBB && "Cannot add a null basic block to the loop!"); assert(LI[NewBB] == 0 && "BasicBlock already in the loop!"); @@ -370,4 +388,68 @@ } } -} // End llvm namespace +/// replaceChildLoopWith - This is used when splitting loops up. It replaces +/// the OldChild entry in our children list with NewChild, and updates the +/// parent pointers of the two loops as appropriate. +void Loop::replaceChildLoopWith(Loop *OldChild, Loop *NewChild) { + assert(OldChild->ParentLoop == this && "This loop is already broken!"); + assert(NewChild->ParentLoop == 0 && "NewChild already has a parent!"); + std::vector::iterator I = std::find(SubLoops.begin(), SubLoops.end(), + OldChild); + assert(I != SubLoops.end() && "OldChild not in loop!"); + *I = NewChild; + OldChild->ParentLoop = 0; + NewChild->ParentLoop = this; + + // Update the loop depth of the new child. + NewChild->setLoopDepth(LoopDepth+1); +} + +/// addChildLoop - Add the specified loop to be a child of this loop. +/// +void Loop::addChildLoop(Loop *NewChild) { + assert(NewChild->ParentLoop == 0 && "NewChild already has a parent!"); + NewChild->ParentLoop = this; + SubLoops.push_back(NewChild); + + // Update the loop depth of the new child. + NewChild->setLoopDepth(LoopDepth+1); +} + +template +static void RemoveFromVector(std::vector &V, T *N) { + typename std::vector::iterator I = std::find(V.begin(), V.end(), N); + assert(I != V.end() && "N is not in this list!"); + V.erase(I); +} + +/// removeChildLoop - This removes the specified child from being a subloop of +/// this loop. The loop is not deleted, as it will presumably be inserted +/// into another loop. +Loop *Loop::removeChildLoop(iterator I) { + assert(I != SubLoops.end() && "Cannot remove end iterator!"); + Loop *Child = *I; + assert(Child->ParentLoop == this && "Child is not a child of this loop!"); + SubLoops.erase(SubLoops.begin()+(I-begin())); + Child->ParentLoop = 0; + return Child; +} + + +/// removeBlockFromLoop - This removes the specified basic block from the +/// current loop, updating the Blocks and ExitBlocks lists as appropriate. This +/// does not update the mapping in the LoopInfo class. +void Loop::removeBlockFromLoop(BasicBlock *BB) { + RemoveFromVector(Blocks, BB); + + // If this block branched out of this loop, remove any exit blocks entries due + // to it. + for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI) + if (!contains(*SI) && *SI != BB) + RemoveFromVector(ExitBlocks, *SI); + + // If any blocks in this loop branch to BB, add it to the exit blocks set. + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) + if (contains(*PI)) + ExitBlocks.push_back(BB); +} From alkis at cs.uiuc.edu Mon Apr 12 15:27:13 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Mon Apr 12 15:27:13 2004 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervals.cpp Message-ID: <200404122026.PAA25886@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: LiveIntervals.cpp updated: 1.69 -> 1.70 --- Log message: Fix bug introduced in previous commit. --- Diffs of the changes: (+1 -1) Index: llvm/lib/CodeGen/LiveIntervals.cpp diff -u llvm/lib/CodeGen/LiveIntervals.cpp:1.69 llvm/lib/CodeGen/LiveIntervals.cpp:1.70 --- llvm/lib/CodeGen/LiveIntervals.cpp:1.69 Mon Apr 12 12:39:20 2004 +++ llvm/lib/CodeGen/LiveIntervals.cpp Mon Apr 12 15:26:39 2004 @@ -138,7 +138,7 @@ if (tii.isMoveInstr(*mii, srcReg, dstReg) && rep(srcReg) == rep(dstReg)) { // remove from def list - Interval& interval = getOrCreateInterval(dstReg); + Interval& interval = getOrCreateInterval(rep(dstReg)); unsigned defIndex = getInstructionIndex(mii); Interval::Defs::iterator d = std::lower_bound( interval.defs.begin(), interval.defs.end(), defIndex); From gaeke at cs.uiuc.edu Mon Apr 12 15:58:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Apr 12 15:58:01 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/TraceOptEmitter.cpp Message-ID: <200404122057.PAA22539@seraph.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: TraceOptEmitter.cpp added (r1.1) --- Log message: This is the MachineCodeEmitter which we'll use to emit optimized traces to memory. The first version you see here is a hacked-up version of the target-independent JIT's Emitter. --- Diffs of the changes: (+194 -0) Index: reopt/lib/LightWtProfiling/TraceOptEmitter.cpp diff -c /dev/null reopt/lib/LightWtProfiling/TraceOptEmitter.cpp:1.1 *** /dev/null Mon Apr 12 15:57:56 2004 --- reopt/lib/LightWtProfiling/TraceOptEmitter.cpp Mon Apr 12 15:57:43 2004 *************** *** 0 **** --- 1,194 ---- + //===-- TraceOptEmitter.cpp - Write machine code to executable memory -----===// + // + // 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. + // + //===----------------------------------------------------------------------===// + // + // The trace reoptimizer uses this MachineCodeEmitter to output + // optimized machine code to memory, so that it can be executed instead of + // the corresponding unoptimized code. + // + // Currently, it uses the same executable memory segment that the + // TraceCache would use, but the TraceCache is unaware of it, so they can + // not be used together. + // + //===----------------------------------------------------------------------===// + + #include "reopt/ScratchMemory.h" + #include "llvm/Constant.h" + #include "llvm/Module.h" + #include "llvm/CodeGen/MachineCodeEmitter.h" + #include "llvm/CodeGen/MachineFunction.h" + #include "llvm/CodeGen/MachineConstantPool.h" + #include "llvm/Target/TargetData.h" + #include "Support/Debug.h" + #include "Support/DynamicLinker.h" + using namespace llvm; + + namespace { + /// TraceOptEmitter - The trace reoptimizer's MachineCodeEmitter, + /// which is used to output functions to memory for execution. + /// + class TraceOptEmitter : public MachineCodeEmitter { + TargetData &TD; + + // CurBlock - The start of the current block of memory. CurByte - The + // current byte being emitted to. + unsigned char *CurBlock, *CurByte; + unsigned char *FunctionBase, *CurFunctionPtr; + + // ConstantPoolAddresses - Contains the location for each entry in the + // constant pool. + std::vector ConstantPoolAddresses; + public: + TraceOptEmitter (TargetData &_TD) : TD (_TD) { + // Re-use the existing DummyFunction area for code emission in the + // Reoptimizer. No memory is reserved for stubs. + FunctionBase = (unsigned char *) dummyFunction2; + // Allocate functions forward from the function base. + CurFunctionPtr = FunctionBase; + } + + virtual void startFunction(MachineFunction &F); + virtual void finishFunction(MachineFunction &F); + virtual void emitConstantPool(MachineConstantPool *MCP); + virtual void startFunctionStub(const Function &F, unsigned StubSize) { + abort (); + } + virtual void* finishFunctionStub(const Function &F) { + abort (); + } + virtual void emitByte(unsigned char B); + virtual void emitWord(unsigned W); + + virtual uint64_t getGlobalValueAddress(GlobalValue *V); + virtual uint64_t getGlobalValueAddress(const std::string &Name); + virtual uint64_t getConstantPoolEntryAddress(unsigned Entry); + virtual uint64_t getCurrentPCValue(); + + // forceCompilationOf - Force the compilation of the specified function, and + // return its address, because we REALLY need the address now. + // + // FIXME: This is JIT specific! + // + virtual uint64_t forceCompilationOf(Function *F); + }; + } + + MachineCodeEmitter *createTraceOptEmitter(TargetData &TD) { + return new TraceOptEmitter(TD); + } + + void TraceOptEmitter::startFunction(MachineFunction &F) { + // Round up to a 64-bit word boundary. + CurBlock = (unsigned char*)(((intptr_t)CurFunctionPtr + 7) & ~7); + CurByte = CurBlock; + } + + void TraceOptEmitter::finishFunction(MachineFunction &F) { + assert(CurByte > CurFunctionPtr); + CurFunctionPtr = CurByte; + + ConstantPoolAddresses.clear(); + + DEBUG(std::cerr << "Finished CodeGen of [" << (void*)CurBlock + << "] Function: " << F.getFunction()->getName() + << ": " << CurByte-CurBlock << " bytes of text\n"); + } + + void TraceOptEmitter::emitConstantPool(MachineConstantPool *MCP) { + const std::vector &Constants = MCP->getConstants(); + if (Constants.empty()) return; + + std::vector ConstantOffset; + ConstantOffset.reserve(Constants.size()); + + // Calculate how much space we will need for all the constants, and the offset + // each one will live in. + unsigned TotalSize = 0; + for (unsigned i = 0, e = Constants.size(); i != e; ++i) { + const Type *Ty = Constants[i]->getType(); + unsigned Size = TD.getTypeSize(Ty); + unsigned Alignment = TD.getTypeAlignment(Ty); + // Make sure to take into account the alignment requirements of the type. + TotalSize = (TotalSize + Alignment-1) & ~(Alignment-1); + + // Remember the offset this element lives at. + ConstantOffset.push_back(TotalSize); + TotalSize += Size; // Reserve space for the constant. + } + + // Now that we know how much memory to allocate, do so. + char *Pool = new char[TotalSize]; + + // Actually output all of the constants, and remember their addresses. + for (unsigned i = 0, e = Constants.size(); i != e; ++i) { + void *Addr = Pool + ConstantOffset[i]; + + // The original code did this: + // TheJIT->InitializeMemory(Constants[i], Addr); + // We need to steal this code from the ExecutionEngine (or something), + // for use in the Reoptimizer. + std::cerr << "FIXME: Can't initialize constants spilled to memory yet\n"; + abort (); + + ConstantPoolAddresses.push_back(Addr); + } + } + + void TraceOptEmitter::emitByte(unsigned char B) { + *CurByte++ = B; // Write the byte to memory + } + + void TraceOptEmitter::emitWord(unsigned W) { + // This won't work if the endianness of the host and target don't agree! (For + // a JIT this can't happen though. :) + *(unsigned*)CurByte = W; + CurByte += sizeof(unsigned); + } + + uint64_t TraceOptEmitter::getGlobalValueAddress(GlobalValue *V) { + intptr_t Result = 0; + if (V->hasName ()) { + Result = (intptr_t)GetAddressOfSymbol (V->getName ()); + } + if (!Result) { + std::cerr << "TraceOptEmitter can't find address of GlobalValue: " << *V; + abort (); + } + return Result; + } + + uint64_t TraceOptEmitter::getGlobalValueAddress(const std::string &Name) { + intptr_t Result = 0; + Result = (intptr_t)GetAddressOfSymbol (Name); + if (!Result) { + std::cerr << "TraceOptEmitter can't find address of \"" << Name << "\"\n"; + abort (); + } + return Result; + } + + // getConstantPoolEntryAddress - Return the address of the 'ConstantNum' entry + // in the constant pool that was last emitted with the 'emitConstantPool' + // method. + // + uint64_t TraceOptEmitter::getConstantPoolEntryAddress(unsigned ConstantNum) { + assert(ConstantNum < ConstantPoolAddresses.size() && + "Invalid ConstantPoolIndex!"); + return (intptr_t)ConstantPoolAddresses[ConstantNum]; + } + + // getCurrentPCValue - This returns the address that the next emitted byte + // will be output to. + // + uint64_t TraceOptEmitter::getCurrentPCValue() { + return (intptr_t)CurByte; + } + + uint64_t TraceOptEmitter::forceCompilationOf(Function *F) { + return getGlobalValueAddress (F); + } From lattner at cs.uiuc.edu Mon Apr 12 15:59:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Apr 12 15:59:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LoopSimplify/2004-04-12-LoopSimplify-SwitchBackedges.ll Message-ID: <200404122059.PAA09061@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LoopSimplify: 2004-04-12-LoopSimplify-SwitchBackedges.ll added (r1.1) --- Log message: new testcase --- Diffs of the changes: (+22 -0) Index: llvm/test/Regression/Transforms/LoopSimplify/2004-04-12-LoopSimplify-SwitchBackedges.ll diff -c /dev/null llvm/test/Regression/Transforms/LoopSimplify/2004-04-12-LoopSimplify-SwitchBackedges.ll:1.1 *** /dev/null Mon Apr 12 15:59:18 2004 --- llvm/test/Regression/Transforms/LoopSimplify/2004-04-12-LoopSimplify-SwitchBackedges.ll Mon Apr 12 15:59:07 2004 *************** *** 0 **** --- 1,22 ---- + ; RUN: llvm-as < %s | opt -loopsimplify -disable-output + + implementation + + void %test() { + loopentry.0: + br label %loopentry.1 + + loopentry.1: + %pixel.4 = phi int [ 0, %loopentry.0 ], [ %pixel.4, %loopentry.1], [ %tmp.370, %then.6 ], [ %tmp.370, %then.6 ] + br bool false, label %then.6, label %loopentry.1 + + then.6: + %tmp.370 = add int 0, 0 ; [#uses=2] + switch uint 0, label %label.7 [ + uint 6408, label %loopentry.1 + uint 32841, label %loopentry.1 + ] + + label.7: ; preds = %then.6 + ret void + } From gaeke at cs.uiuc.edu Mon Apr 12 16:47:02 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Apr 12 16:47:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp Message-ID: <200404122146.QAA25233@seraph.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9TargetMachine.cpp updated: 1.108 -> 1.109 --- Log message: We don't need to insert TargetData into the PassManager here. --- Diffs of the changes: (+0 -5) Index: llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp diff -u llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.108 llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.109 --- llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp:1.108 Fri Apr 2 11:52:40 2004 +++ llvm/lib/Target/SparcV9/SparcV9TargetMachine.cpp Mon Apr 12 16:46:31 2004 @@ -199,11 +199,6 @@ /// generation for the UltraSparcV9. /// void SparcV9JITInfo::addPassesToJITCompile(FunctionPassManager &PM) { - const TargetData &TD = TM.getTargetData(); - - PM.add(new TargetData("lli", TD.isLittleEndian(), TD.getPointerSize(), - TD.getPointerAlignment(), TD.getDoubleAlignment())); - // Replace malloc and free instructions with library calls. PM.add(createLowerAllocationsPass()); From gaeke at cs.uiuc.edu Mon Apr 12 17:53:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Apr 12 17:53:01 2004 Subject: [llvm-commits] CVS: llvm/utils/Spiff/ Message-ID: <200404122253.RAA24864@zion.cs.uiuc.edu> Changes in directory llvm/utils/Spiff: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/utils/Spiff added to the repository --- Diffs of the changes: (+0 -0) From gaeke at cs.uiuc.edu Mon Apr 12 17:54:02 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Apr 12 17:54:02 2004 Subject: [llvm-commits] CVS: llvm/utils/Spiff/LICENSE.TXT Makefile README command.c command.h comment.c comment.h compare.c compare.h edit.h exact.c exact.h flagdefs.h float.c float.h floatrep.c floatrep.h line.c line.h miller.c miller.h misc.c misc.h output.c output.h paper.ms parse.c parse.h spiff.1 spiff.c strings.c strings.h token.c token.h tol.c tol.h visual.c visual.h Message-ID: <200404122253.RAA24969@zion.cs.uiuc.edu> Changes in directory llvm/utils/Spiff: LICENSE.TXT added (r1.1) Makefile added (r1.1) README added (r1.1) command.c added (r1.1) command.h added (r1.1) comment.c added (r1.1) comment.h added (r1.1) compare.c added (r1.1) compare.h added (r1.1) edit.h added (r1.1) exact.c added (r1.1) exact.h added (r1.1) flagdefs.h added (r1.1) float.c added (r1.1) float.h added (r1.1) floatrep.c added (r1.1) floatrep.h added (r1.1) line.c added (r1.1) line.h added (r1.1) miller.c added (r1.1) miller.h added (r1.1) misc.c added (r1.1) misc.h added (r1.1) output.c added (r1.1) output.h added (r1.1) paper.ms added (r1.1) parse.c added (r1.1) parse.h added (r1.1) spiff.1 added (r1.1) spiff.c added (r1.1) strings.c added (r1.1) strings.h added (r1.1) token.c added (r1.1) token.h added (r1.1) tol.c added (r1.1) tol.h added (r1.1) visual.c added (r1.1) visual.h added (r1.1) --- Log message: Add the Spiff fp-aware diff utility from Bellcore --- Diffs of the changes: (+6986 -0) Index: llvm/utils/Spiff/LICENSE.TXT diff -c /dev/null llvm/utils/Spiff/LICENSE.TXT:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/LICENSE.TXT Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,18 ---- + The copyright below applies to Spiff 1.0 as redistributed as part of LLVM + and/or its test suite. + + ------------------------------------------------------------------------------ + + COPYRIGHT + + Our lawyers advise the following: + + Copyright (c) 1988 Bellcore + All Rights Reserved + Permission is granted to copy or use this program, EXCEPT that it + may not be sold for profit, the copyright notice must be reproduced + on copies, and credit should be given to Bellcore where it is due. + BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + + Given that all of the above seems to be very reasonable, there should be no + reason for anyone to not play by the rules. Index: llvm/utils/Spiff/Makefile diff -c /dev/null llvm/utils/Spiff/Makefile:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/Makefile Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,6 ---- + LEVEL = ../.. + TOOLNAME = spiff + + include $(LEVEL)/Makefile.common + + CPPFLAGS += -DATT -DNOCHATTER Index: llvm/utils/Spiff/README diff -c /dev/null llvm/utils/Spiff/README:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/README Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,264 ---- + INSTALLATION + 1) Change makefile settings to reflect + ATT vs. BSD software + termio vs. termcap + MGR vs. no MGR (MGR is a BELLCORE produced + window manager that is also available + free to the public.) + 2) Then, just say "make". + If you want to "make install", you should first + change definition of INSDIR in the makefile + + 3) to test the software say + + spiff Sample.1 Sample.2 + + spiff should find 4 differences and + you should see the words "added", "deleted", "changed", + and "altered" as well as four number in stand-out mode. + + spiff Sample.1 Sample.2 | cat + + should produce the same output, only the differences + should be underlined However, on many terminals the underlining + does not appear. So try the command + + spiff Sample.1 Sample.2 | cat -v + + or whatever the equivalent to cat -v is on your system. + + A more complicated test set is found in Sample.3 and Sample.4 + These files show how to use embedded commands to do things + like change the commenting convention and tolerances on the + fly. Be sure to run the command with the -s option to spiff: + + spiff -s 'command spiffword' Sample.3 Sample.4 + + These files by no means provide an exhaustive test of + spiff's features. But they should give you some idea if things + are working right. + + This code (or it's closely related cousins) has been run on + Vaxen running 4.3BSD, a CCI Power 6, some XENIX machines, and some + other machines running System V derivatives as well as + (thanks to eugene at ames.arpa) Cray, Amdahl and Convex machines. + + 4) Share and enjoy. + + AUTHOR'S ADDRESS + Please send complaints, comments, praise, bug reports, etc to + Dan Nachbar + Bell Communications Research (also known as BELLCORE) + 445 South St. Room 2B-389 + Morristown, NJ 07960 + + nachbar at bellcore.com + or + bellcore!nachbar + or + (201) 829-4392 (praise only, please) + + OVERVIEW OF OPERATION + + Each of two input files is read and stored in core. + Then it is parsed into a series of tokens (literal strings and + floating point numbers, white space is ignored). + The token sequences are stored in core as well. + After both files have been parsed, a differencing algorithm is applied to + the token sequences. The differencing algorithm + produces an edit script, which is then passed to an output routine. + + SIZE LIMITS AND OTHER DEFAULTS + file implementing limit name default value + maximum number of lines lines.h _L_MAXLINES 10000 + per file + maximum number of tokens token.h K_MAXTOKENS 50000 + per file + maximum line length misc.h Z_LINELEN 1024 + maximum word length misc.h Z_WORDLEN 20 + (length of misc buffers for + things like literal + delimiters. + NOT length of tokens which + can be virtually any length) + default absolute tolerance tol.h _T_ADEF "1e-10" + default relative tolerance tol.h _T_RDEF "1e-10" + maximum number of commands command.h _C_CMDMAX 100 + in effect at one time + maximum number of commenting comment.h W_COMMAX 20 + conventions that can be + in effect at one time + (not including commenting + conventions that are + restricted to beginning + of line) + maximum number of commenting comment.h W_BOLMAX 20 + conventions that are + restricted to beginning of + line that are in effect at + one time + maximum number of literal comment.h W_LITMAX 20 + string conventions that + can be in effect at one time + maximum number of tolerances tol.h _T_TOLMAX 10 + that can be in effect at one + time + + + DIFFERENCES BETWEEN THE CURRENT VERSION AND THE ENCLOSED PAPER + + The files paper.ms and paper.out contain the nroff -ms input and + output respectively of a paper on spiff that was given the Summer '88 + USENIX conference in San Francisco. Since that time many changes + have been made to the code. Many flags have changed and some have + had their meanings reversed, see the enclosed man page for the current + usage. Also, there is no longer control over the + granularity of object used when applying the differencing algorithm. + The current version of spiff always applies the differencing + in terms of individual tokens. The -t flag controls how the edit script + is printed. This arrangement more closely reflects the original intent + of having multiple differencing granularities. + + PERFORMANCE + + Spiff is big and slow. It is big because all the storage is + in core. It is a straightforward but boring task to move the temporary + storage into a file. Someone who cares is invited to take on the job. + Spiff is slow because whenever a choice had to be made between + speed of operation and ease of coding, speed of operation almost always lost. + As the program matures it will almost certainly get smaller and faster. + Obvious performance enhancements have been avoided in order to make the + program available as soon as possible. + + COPYRIGHT + + Our lawyers advise the following: + + Copyright (c) 1988 Bellcore + All Rights Reserved + Permission is granted to copy or use this program, EXCEPT that it + may not be sold for profit, the copyright notice must be reproduced + on copies, and credit should be given to Bellcore where it is due. + BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + + Given that all of the above seems to be very reasonable, there should be no + reason for anyone to not play by the rules. + + + NAMING CONVENTIONS USED IN THE CODE + + All symbols (functions, data declarations, macros) are named as follows: + + L_foo -- for names exported to other modules + and possibly used inside the module as well. + _L_foo -- for names used by more than one routine + within a module + foo -- for names used inside a single routine. + + Each module uses a different value for "L" -- + module files letter used implements + spiff.c Y top level routines + misc.[ch] Z various routines used throughout + strings.[ch] S routines for handling strings + edit.h E list of changes found and printed + tol.[ch] T tolerances for real numbers + token.[ch] K storage for objects + float.[ch] F manipulation of floats + floatrep.[ch] R representation of floats + line.[ch] L storage for input lines + parse.[ch] P parse for input files + command.[ch] C storage and recognition of commands + comment.[ch] W comment list maintenance + compare.[ch] X comparisons of a single token + exact.[ch] Q exact match differencing algorithm + miller.[ch] G miller/myers differencing algorithm + output.[ch] O print listing of differences + flagdefs.h U define flag bits that are used in + several of the other modules. + These #defines could have been + included in misc.c, but were separated + out because of their explicit + communication function. + visual.[ch] V screen oriented display for MGR + window manager, also contains + dummy routines for people who don't + have MGR + + I haven't cleaned up visual.c yet. It probably doesn't even compile + in this version anyway. But since most people don't have mgr, this + isn't urgent. + + NON-OBVIOUS DATA STRUCTURES + + The Floating Point Representation + + Floating point numbers are stored in a struct R_flstr + The fractional part is often called the mantissa. + + The structure consists of + a flag for the sign of the factional part + the exponent in binary + a character string containing the fractional part + + The structure could be converted to a float via + atof(strcat(".",mantissa)) * (10^exponent) + + To be properly formed, the mantissa string must: + start with a digit between 1 and 9 (i.e. no leading zeros) + except for the zero, in which case the mantissa is exactly "0" + for the special case of zero, the exponent is always 0, and the + sign is always positive. (i.e. no negative 0) + + In other words, (except for the value 0) + the mantissa is a fractional number ranging + between 0.1 (inclusive) and 1.0 (exclusive). + The exponent is interpreted as a power of 10. + + Lines + there are three sets of lines: + implemented in line.c and line.h + real_lines -- + the lines as they come from the file + content_lines -- + a subset of reallines that excluding embedded commands + implemented in token.c and token.h + token_lines -- + a subset of content_lines consisting of those lines that + have tokens that begin on them (literals can go on for + more than one line) + i.e. content_lines excluding comments and blank lines. + + + THE STATE OF THE CODE + Things that should be added + visual mode should handle tabs and wrapped lines + handling huge files in chunks when in using the ordinal match + algorithm. right now you have to parse and then diff the + whole thing before you get any output. often, you run out of memory. + + Things that would be nice to add + output should optionally be expressed in real line numbers + (i.e. including command lines) + at present, all storage is in core. there should + be a compile time decision to allow temporary storage + in files rather than core. + that way the user could decide how to handle the + speed/space tradeoff + a front end that looked like diff should be added so that + one could drop spiff into existing shell scripts + the parser converts floats into their internal form even when + it isn't necessary. + in the miller/myer code, the code should check for matching + end sequences. it currently looks matching beginning + sequences. + + Minor programming improvements (programming botches) + some of the #defines should really be enumerated types + all the routines in strings.c that alter the data at the end of + a pointer but return void should just return the correct + data. the current arrangement is a historical artifact + of the days when these routines returned a status code. + but then the code was never examined, + so i made them void . . . + comments should be added to the miller/myer code + in visual mode, ask for font by name rather than number Index: llvm/utils/Spiff/command.c diff -c /dev/null llvm/utils/Spiff/command.c:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/command.c Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,193 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef lint + static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/command.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; + #endif + + + #include "misc.h" + #include "tol.h" + #include "comment.h" + #include "command.h" + #include "strings.h" + #include "parse.h" + + /* + ** storage for the string that signals an embedded command + */ + static char _C_cmdword[Z_WORDLEN]; + + /* + ** storage for the command script + */ + static int _C_nextcmd = 0; + static char *_C_cmds[_C_CMDMAX]; + + + /* + ** add a string to the command buffer + */ + void + C_addcmd(str) + char *str; + { + S_savestr(&_C_cmds[_C_nextcmd++],str); + return; + } + + /* + ** execute a single command + */ + static void + _C_do_a_cmd(str) + char *str; + { + /* + ** place holder for the beginning of the string + */ + char *beginning = str; + + S_skipspace(&str); + + /* + ** set the command string to allow embedded commands + */ + if (!S_wordcmp(str,"command")) + { + S_nextword(&str); + if (strlen(str) >= Z_WORDLEN) + { + Z_fatal("command word is too long"); + } + S_wordcpy(_C_cmdword,str); + } + /* + ** set the tolerances + */ + else if (!S_wordcmp(str,"tol")) + { + S_nextword(&str); + T_tolline(str); + } + /* + ** add a comment specification + */ + else if (!S_wordcmp(str,"comment")) + { + S_nextword(&str); + if (strlen(str) >= Z_WORDLEN) + { + Z_fatal("command word is too long"); + } + W_addcom(str,0); + } + else if (!S_wordcmp(str,"nestcom")) + { + S_nextword(&str); + if (strlen(str) >= Z_WORDLEN) + { + Z_fatal("command word is too long"); + } + W_addcom(str,1); + } + /* + ** add a literal string specification + */ + else if (!S_wordcmp(str,"literal")) + { + S_nextword(&str); + if (strlen(str) >= Z_WORDLEN) + { + Z_fatal("command word is too long"); + } + W_addlit(str); + } + else if (!S_wordcmp(str,"resetcomments")) + { + W_clearcoms(); + } + else if (!S_wordcmp(str,"resetliterals")) + { + W_clearlits(); + } + else if (!S_wordcmp(str,"beginchar")) + { + S_nextword(&str); + W_setbolchar(*str); + } + else if (!S_wordcmp(str,"endchar")) + { + S_nextword(&str); + W_seteolchar(*str); + } + else if (!S_wordcmp(str,"addalpha")) + { + S_nextword(&str); + P_addalpha(str); + } + else if ((0 == strlen(str)) || !S_wordcmp(str,"rem") + || ('#' == *str)) + { + /* do nothing */ + } + else + { + (void) sprintf(Z_err_buf, + "don't understand command %s\n", + beginning); + Z_fatal(Z_err_buf); + } + return; + } + + /* + ** execute the commands in the command buffer + */ + void + C_docmds() + { + int i; + for (i=0;i<_C_nextcmd;i++) + { + _C_do_a_cmd(_C_cmds[i]); + } + return; + } + + /* + ** disable embedded command key word recognition + */ + void + C_clear_cmd() + { + _C_cmdword[0] = '\0'; + return; + } + + #define inline spiff_inline + int + C_is_cmd(inline) + char *inline; + { + char *ptr; + /* + ** see if this is a command line + ** and if so, do the command right away + */ + if (('\0' != _C_cmdword[0]) && (!S_wordcmp(inline,_C_cmdword))) + { + ptr = inline; + S_nextword(&ptr); + _C_do_a_cmd(ptr); + return(1); + } + return(0); + } + Index: llvm/utils/Spiff/command.h diff -c /dev/null llvm/utils/Spiff/command.h:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/command.h Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,18 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + #ifndef C_INCLUDED + extern int C_is_cmd(); + extern void C_clear_cmd(); + extern void C_addcmd(); + extern void C_docmds(); + + #define _C_CMDMAX 100 + + #define C_INCLUDED + #endif Index: llvm/utils/Spiff/comment.c diff -c /dev/null llvm/utils/Spiff/comment.c:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/comment.c Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,307 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef lint + static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/comment.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; + #endif + + + #include "misc.h" + #include "comment.h" + #include "strings.h" + + /* + ** storage for the comment specifiers that can appear + ** anywhere on a line + */ + static int _W_nextcom = 0; + _W_comstruct _W_coms[_W_COMMAX]; + + /* + ** storage for comment specifiers that are examined only at the + ** beginning of each line + */ + static int _W_nextbol = 0; + _W_bolstruct _W_bols[_W_BOLMAX]; + + /* + ** storage for delimiters of literal strings + */ + static int _W_nextlit = 0; + _W_litstruct _W_lits[_W_LITMAX]; + + /* + ** storage for characters to specify beginning and end of line + ** in the comment and literal commands + */ + char _W_bolchar = '^'; + char _W_eolchar = '$'; + + + /* + ** build up a list of comment delimiters + */ + void + W_addcom(str,nestflag) + char *str; + int nestflag; + { + /* + ** check for comments that begin at the beginning of line + */ + if (*str == _W_bolchar) + { + if (_W_nextbol >= _W_BOLMAX) + Z_fatal("too many beginning of line comment delimiter sets"); + + str++; /*skip the bol char */ + S_wordcpy(_W_bols[_W_nextbol].begin,str); + + S_nextword(&str); + + if (*str == _W_eolchar) + { + (void) strcpy(_W_bols[_W_nextbol].end,"\n"); + } + else + { + S_wordcpy(_W_bols[_W_nextbol].end,str); + } + + S_nextword(&str); + S_wordcpy(_W_bols[_W_nextbol].escape,str); + + /* + ** + */ + if (nestflag) + Z_complain("begining of line comment won't nest"); + + _W_nextbol++; + } + else + { + if (_W_nextcom >= _W_COMMAX) + Z_fatal("too many comment delimiter sets"); + + S_wordcpy(_W_coms[_W_nextcom].begin,str); + + S_nextword(&str); + + if (*str == _W_eolchar) + { + (void) strcpy(_W_coms[_W_nextbol].end,"\n"); + } + else + { + S_wordcpy(_W_coms[_W_nextbol].end,str); + } + + S_nextword(&str); + S_wordcpy(_W_coms[_W_nextcom].escape,str); + + _W_coms[_W_nextcom].nestbit = nestflag; + + _W_nextcom++; + } + return; + } + + + /* + ** clear the comment delimiter storage + */ + void + W_clearcoms() + { + _W_nextcom = 0; + _W_nextbol = 0; + return; + } + + /* + ** build up the list of literal delimiters + */ + void + W_addlit(str) + char *str; + { + if (_W_nextlit >= _W_LITMAX) + Z_fatal("too many literal delimiter sets"); + + S_wordcpy(_W_lits[_W_nextlit].begin,str); + + S_nextword(&str); + S_wordcpy(_W_lits[_W_nextlit].end,str); + + S_nextword(&str); + S_wordcpy(_W_lits[_W_nextlit].escape,str); + + _W_nextlit++; + return; + } + + /* + ** clear the literal delimiter storage + */ + void + W_clearlits() + { + _W_nextlit = 0; + return; + } + + + + static _W_bolstruct bol_scratch; + + static void + _W_copybol(to,from) + W_bol to,from; + { + (void) strcpy(to->begin,from->begin); + (void) strcpy(to->end,from->end); + (void) strcpy(to->escape,from->escape); + } + + W_bol + W_isbol(str) + char *str; + { + int i; + + for(i=0;i<_W_nextbol;i++) + { + if(!S_wordcmp(str,_W_bols[i].begin)) + { + _W_copybol(&bol_scratch,&_W_bols[i]); + return(&bol_scratch); + } + } + return(W_BOLNULL); + } + + W_is_bol(ptr) + W_bol ptr; + { + int i; + + for(i=0;i<_W_nextbol;i++) + { + if(!S_wordcmp(ptr->begin,_W_bols[i].begin) && + !S_wordcmp(ptr->end,_W_bols[i].end) && + !S_wordcmp(ptr->escape,_W_bols[i].escape)) + { + return(1); + } + + } + return(0); + } + + + static _W_litstruct lit_scratch; + + static void + _W_copylit(to,from) + W_lit to,from; + { + (void) strcpy(to->begin,from->begin); + (void) strcpy(to->end,from->end); + (void) strcpy(to->escape,from->escape); + } + + W_lit + W_islit(str) + char *str; + { + int i; + + for(i=0;i<_W_nextlit;i++) + { + if(!S_wordcmp(str,_W_lits[i].begin)) + { + _W_copylit(&lit_scratch,&_W_lits[i]); + return(&lit_scratch); + } + } + return(W_LITNULL); + } + + W_is_lit(ptr) + W_lit ptr; + { + int i; + + for(i=0;i<_W_nextlit;i++) + { + if(!S_wordcmp(ptr->begin,_W_lits[i].begin) && + !S_wordcmp(ptr->end,_W_lits[i].end) && + !S_wordcmp(ptr->escape,_W_lits[i].escape)) + { + return(1); + } + + } + return(0); + } + + static _W_comstruct com_scratch; + + static void + _W_copycom(to,from) + W_com to,from; + { + (void) strcpy(to->begin,from->begin); + (void) strcpy(to->end,from->end); + (void) strcpy(to->escape,from->escape); + to->nestbit = from->nestbit; + } + + W_com + W_iscom(str) + char *str; + { + int i; + + for(i=0;i<_W_nextcom;i++) + { + if(!S_wordcmp(str,_W_coms[i].begin)) + { + _W_copycom(&com_scratch,&_W_coms[i]); + return(&com_scratch); + } + } + return(W_COMNULL); + } + + W_is_com(ptr) + W_com ptr; + { + int i; + + for(i=0;i<_W_nextcom;i++) + { + if(!S_wordcmp(ptr->begin,_W_coms[i].begin) && + !S_wordcmp(ptr->end,_W_coms[i].end) && + !S_wordcmp(ptr->escape,_W_coms[i].escape) && + ptr->nestbit == _W_coms[i].nestbit) + { + return(1); + } + + } + return(0); + } + + W_is_nesting(ptr) + W_com ptr; + { + return(ptr->nestbit); + } Index: llvm/utils/Spiff/comment.h diff -c /dev/null llvm/utils/Spiff/comment.h:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/comment.h Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,84 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + #ifndef W_INCLUDED + + #include + + #define _W_COMWORD 16 + #define _W_COMMAX 20 + #define _W_BOLMAX 20 + #define _W_LITMAX 20 + + /* + ** these three data structures used to be much + ** different. eventually, the differences + ** have disappeared as the code has evolved. + ** obviously, they should now be collapsed. + ** someday . . . + */ + typedef struct { + char begin[_W_COMWORD]; + char end[_W_COMWORD]; + char escape[_W_COMWORD]; + } _W_bolstruct, *W_bol; + + typedef struct { + char begin[_W_COMWORD]; + char end[_W_COMWORD]; + char escape[_W_COMWORD]; + int nestbit; + } _W_comstruct, *W_com; + + typedef struct { + char begin[_W_COMWORD]; + char end[_W_COMWORD]; + char escape[_W_COMWORD]; + } _W_litstruct, *W_lit; + + #define W_bolbegin(ptr) (ptr->begin) + #define W_bolend(ptr) (ptr->end) + #define W_bolescape(ptr) (ptr->escape) + + #define W_litbegin(ptr) (ptr->begin) + #define W_litend(ptr) (ptr->end) + #define W_litescape(ptr) (ptr->escape) + + #define W_combegin(ptr) (ptr->begin) + #define W_comend(ptr) (ptr->end) + #define W_comescape(ptr) (ptr->escape) + + extern char _W_bolchar; + extern char _W_eolchar; + + #define W_setbolchar(x) (_W_bolchar = x) + #define W_seteolchar(x) (_W_eolchar = x) + + extern W_bol W_isbol(); + extern W_lit W_islit(); + extern W_com W_iscom(); + + extern int W_is_bol(); + extern int W_is_lit(); + extern int W_is_com(); + + extern _W_bolstruct _W_bols[]; + extern _W_litstruct _W_lits[]; + extern _W_comstruct _W_coms[]; + + extern void W_clearcoms(); + extern void W_clearlits(); + extern void W_addcom(); + extern void W_addlit(); + + #define W_BOLNULL ((W_bol)0) + #define W_COMNULL ((W_com)0) + #define W_LITNULL ((W_lit)0) + + #define W_INCLUDED + #endif Index: llvm/utils/Spiff/compare.c diff -c /dev/null llvm/utils/Spiff/compare.c:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/compare.c Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,209 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef lint + static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/compare.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; + #endif + + #include "misc.h" + #include "flagdefs.h" + #include "tol.h" + #include "token.h" + #include "line.h" + #include "float.h" + #include "compare.h" + + #include + + X_com(a,b,flags) + int a,b,flags; + { + K_token atmp,btmp; + + atmp = K_gettoken(0,a); + btmp = K_gettoken(1,b); + if(flags & U_BYTE_COMPARE) + { + return(_X_strcmp(K_gettext(atmp),K_gettext(btmp),flags)); + } + else + { + return(_X_cmptokens(atmp,btmp,flags)); + } + #ifndef lint + Z_fatal("this line should never be reached in com"); + return(-1); /* Z_fatal never returns, but i need a this line + here to stop lint from complaining */ + #endif + } + + /* + ** same as strcmp() except that case can be optionally ignored + */ + static int + _X_strcmp(s1,s2,flags) + char *s1,*s2; + int flags; + { + if (flags & U_NO_CASE) + { + + for (;('\0' != s1) && ('\0' != *s2);s1++,s2++) + { + if(isalpha(*s1) && isalpha(*s2)) + { + if(tolower(*s1) != tolower(*s2)) + { + return(1); + } + } + else + { + if(*s1!=*s2) + { + return(1); + } + } + } + return(*s1 != *s2); + } + else + { + return(strcmp(s1,s2)); + } + } + + + /* + ** routine to compare two tokens + */ + static int + _X_cmptokens(p1,p2,flags) + K_token p1, p2; + int flags; + { + if (K_gettype(p1) != K_gettype(p2)) + { + return(1); + } + + switch (K_gettype(p1)) + { + case K_LIT: + return(_X_strcmp(K_gettext(p1),K_gettext(p2),flags)); + case K_FLO_NUM: + return(_X_floatdiff(K_getfloat(p1), + K_getfloat(p2), + T_picktol(K_gettol(p1), + K_gettol(p2)))); + default: + Z_fatal("fell off switch in _X_cmptokens"); + return(-1); /* Z_fatal never returns, but i need a this line + here to stop lint from complaining */ + } + + } + + /* + ** compare two F_floats using a tolerance + */ + static int + _X_floatdiff(p1,p2,the_tol) + F_float p1,p2; + T_tol the_tol; + { + F_float diff, float_tmp; + T_tol tol_tmp; + + /* + ** check for null tolerance list + */ + if (T_isnull(the_tol)) + { + Z_fatal("_X_floatdiff called with a null tolerance"); + } + + /* + ** look for an easy answer. i.e -- check + ** to see if any of the tolerances are of type T_IGNORE + ** or if the numbers are too small to exceed an absolute + ** tolerance. + ** if so, return immediately + */ + for(tol_tmp=the_tol; !(T_isnull(tol_tmp)) ;tol_tmp=T_getnext(tol_tmp)) + { + if ((T_IGNORE == T_gettype(tol_tmp)) || + /* + ** take a look at the exponents before you bother + ** with the mantissas + */ + ((T_ABSOLUTE == T_gettype(tol_tmp)) + && !F_zerofloat(T_getfloat(tol_tmp)) + && (F_getexp(p1) < + F_getexp(T_getfloat(tol_tmp))-1) + && (F_getexp(p2) < + F_getexp(T_getfloat(tol_tmp))-1))) + { + return(0); + } + } + + + /* + ** ok, we're going to have to do some arithmetic, so + ** first find the magnitude of the difference + */ + if (F_getsign(p1) != F_getsign(p2)) + { + diff = F_floatmagadd(p1,p2); + } + else + { + diff = F_floatsub(p1,p2); + } + + /* + ** now check to see if the difference exceeds any tolerance + */ + for(tol_tmp=the_tol; !(T_isnull(tol_tmp)) ;tol_tmp=T_getnext(tol_tmp)) + { + float_tmp = T_getfloat(tol_tmp); + + if (T_gettype(tol_tmp) == T_ABSOLUTE) + { + /* do nothing */ + } + else if (T_gettype(tol_tmp) == T_RELATIVE) + { + if (F_floatcmp(p1,p2) > 0) + { + float_tmp = F_floatmul(p1, float_tmp); + } + else + { + float_tmp = F_floatmul(p2, float_tmp); + } + } + else + { + Z_fatal("bad value for type of tolerance in floatdiff"); + } + /* + ** if we pass this tolerance, then we're done + */ + if (F_floatcmp(diff,float_tmp) <= 0) + { + return(0); + } + } + /* + ** all of the tolerances were exceeded + */ + return(1); + } Index: llvm/utils/Spiff/compare.h diff -c /dev/null llvm/utils/Spiff/compare.h:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/compare.h Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,14 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + #ifndef X_INCLUDED + + extern int X_com(); + + #define X_INCLUDED + #endif Index: llvm/utils/Spiff/edit.h diff -c /dev/null llvm/utils/Spiff/edit.h:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/edit.h Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,43 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + /* + ** the naming information hiding conventions are incompletely implemented + ** for the edit module. I tried to clean it up once, but kept introducing + ** nasty (ie. core dump) bugs in the miller code. I give up for now. + */ + #ifndef E_INCLUDED + + #define E_INSERT 1 + #define E_DELETE 2 + + typedef struct edt { + struct edt *link; + int op; + int line1; + int line2; + } _E_struct, *E_edit; + + #define E_setop(x,y) ((x)->op = (y)) + #define E_setl1(x,y) ((x)->line1 = (y)) + #define E_setl2(x,y) ((x)->line2 = (y)) + #define E_setnext(x,y) ((x)->link = (y)) + + #define E_getop(x) ((x)->op) + #define E_getl1(x) ((x)->line1) + #define E_getl2(x) ((x)->line2) + #define E_getnext(x) ((x)->link) + + #define E_NULL ((E_edit) 0) + #define E_edit_alloc() (Z_ALLOC(1,_E_struct)) + + #define E_INCLUDED + + #endif + + Index: llvm/utils/Spiff/exact.c diff -c /dev/null llvm/utils/Spiff/exact.c:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/exact.c Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,92 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef lint + static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/exact.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; + #endif + + #include "misc.h" + #include "edit.h" + + /* + ** routine to compare each object with its ordinal twin + */ + E_edit + Q_do_exact(size1,size2,max_d,comflags) + int size1; + int size2; + int max_d; + int comflags; + { + int i = 0; + int diffcnt = 0; + int last = Z_MIN(size1,size2); + int next_edit = 0; + E_edit last_ptr = E_NULL; + int start,tmp; + E_edit *script; + + script = Z_ALLOC(max_d+1,E_edit); + + if (size1 != size2) + { + (void) sprintf(Z_err_buf,"unequal number of tokens, %d and %d respectively\n",size1,size2); + Z_complain(Z_err_buf); + } + + do + { + /* + ** skip identical objects + */ + while (i= max_d+1) + Z_exceed(max_d); + i++; + } + /* + ** build the list of deletions + */ + for(tmp=start;tmp + #include "misc.h" + #include "floatrep.h" + #include "float.h" + #include "strings.h" + + #define _F_GETEND(x) (x + (strlen(x)-1)) + + /* + int floatcnt = 0; + */ + /* + ** routines to convert strings to our internal floating point form + ** isfloat just looks at the string + ** to see if a conversion is reasonable + ** it does look-ahead on when it sees an 'e' and such. + ** atocf actually does the conversion. + ** these two routines could probably be combined + */ + + /* + ** test to see if the string can reasonably + ** be interpreted as floating point number + ** returns 0 if string can't be interpreted as a float + ** otherwise returns the number of digits that will be used in F_atof + */ + F_isfloat(str,need_decimal,allow_sign) + char *str; + int need_decimal; /* if non-zero, require that a decimal point be present + otherwise, accept strings like "123" */ + int allow_sign; /* if non-zero, allow + or - to set the sign */ + { + int man_length = 0; /* length of the fractional part (mantissa) */ + int exp_length = 0; /* length of the exponential part */ + int got_a_digit = 0; /* flag to set if we ever see a digit */ + + /* + ** look for an optional leading sign marker + */ + if (allow_sign && ('+' == *str || '-' == *str)) + { + str++; man_length++; + } + /* + ** count up the digits on the left hand side + ** of the decimal point + */ + while(isdigit(*str)) + { + got_a_digit = 1; + str++; man_length++; + } + + /* + ** check for a decimal point + */ + if ('.' == *str) + { + str++; man_length++; + } + else + { + if (need_decimal) + { + return(0); + } + } + + /* + ** collect the digits on the right hand + ** side of the decimal point + */ + while(isdigit(*str)) + { + got_a_digit = 1; + str++; man_length++; + } + + if (!got_a_digit) + return(0); + + /* + ** now look ahead for an exponent + */ + if ('e' == *str || + 'E' == *str || + 'd' == *str || + 'D' == *str) + { + str++; exp_length++; + if ('+' == *str || '-' == *str) + { + str++; exp_length++; + } + + if (!isdigit(*str)) + { + /* + ** look ahead went too far, + ** so return just the length of the mantissa + */ + return(man_length); + } + + while (isdigit(*str)) + { + str++; exp_length++; + } + } + return(man_length+exp_length); /* return the total length */ + } + + /* + ** routine to convert a string to our internal + ** floating point representation + ** + ** similar to atof() + */ + F_float + F_atof(str,allflag) + char *str; + int allflag; /* require that exactly all the characters are used */ + { + char *beg = str; /* place holder for beginning of the string */ + char man[R_MANMAX]; /* temporary location to build the mantissa */ + int length = 0; /* length of the mantissa so far */ + int got_a_digit = 0; /* flag to set if we get a non-zero digit */ + int i; + int resexp; + + F_float res; /* where we build the result */ + + /* + floatcnt++; + */ + res = R_makefloat(); + + R_setsign(res,R_POSITIVE); + + resexp = 0; + man[0] = '\0'; + + /* + ** check for leading sign + */ + if ('+' == *str) + { + /* + ** sign should already be positive, see above in this + ** routine, so just skip the plus sign + */ + str++; + } + else + { + if ('-' == *str) + { + R_setsign(res,R_NEGATIVE); + str++; + } + } + + /* + ** skip any leading zeros + */ + while('0' == *str) + { + str++; + } + + /* + ** now snarf up the digits on the left hand side + ** of the decimal point + */ + while(isdigit(*str)) + { + got_a_digit = 1; + man[length++] = *str++; + man[length] = '\0'; + resexp++; + } + + /* + ** skip the decimal point if there is one + */ + if ('.' == *str) + str++; + + /* + ** trim off any leading zeros (on the right hand side) + ** if there were no digits in front of the decimal point. + */ + + if (!got_a_digit) + { + while('0' == *str) + { + str++; + resexp--; + } + } + + /* + ** now snarf up the digits on the right hand side + */ + while(isdigit(*str)) + { + man[length++] = *str++; + man[length] = '\0'; + } + + if ('e' == *str || + 'E' == *str || + 'd' == *str || + 'D' == *str ) + { + str++; + resexp += atoi(str); + } + + if (allflag) + { + if ('+' == *str || + '-' == *str) + { + str++; + } + while (isdigit(*str)) + { + str++; + } + if ('\0' != *str) + { + (void) sprintf(Z_err_buf, + "didn't use up all of %s in atocf", + beg); + Z_fatal(Z_err_buf); + } + } + + /* + ** check for special case of all zeros in the mantissa + */ + for (i=0;i= s1) || ( end2 >= s2)) + { + if (end1 >= s1) + { + val1 = *end1 - '0'; + --end1; + } + else + { + val1 = 0; + } + + if (end2 >= s2) + { + val2 = *end2 - '0'; + --end2; + } + else + { + val2 = 0; + } + + tmp = val1 + val2 + carry; + if (tmp > 9) + { + carry = 1; + tmp -= 10; + } + else + { + carry = 0; + } + + *resptr-- = tmp+'0'; + } + if (carry) + { + *resptr = '1'; + } + else + { + resptr++; + } + (void) strcpy(s1,resptr); + return; + } + + /* + ** add zero(s) onto the end of a string + */ + static void + addzeros(ptr,count) + char *ptr; + int count; + { + for(;count> 0;count--) + { + (void) strcat(ptr,"0"); + } + return; + } + + /* + ** subtract two mantissa strings + */ + F_float + F_floatsub(p1,p2) + F_float p1,p2; + { + static F_float result; + static needinit = 1; + static char man1[R_MANMAX],man2[R_MANMAX],diff[R_MANMAX]; + int exp1,exp2; + char *diffptr,*big,*small; + int man_cmp_val,i,borrow; + + if (needinit) + { + result = R_makefloat(); + needinit = 0; + } + + man1[0] = '\0'; + man2[0] = '\0'; + + exp1 = R_getexp(p1); + exp2 = R_getexp(p2); + + /* + ** line up the mantissas + */ + while (exp1 < exp2) + { + (void) strcat(man1,"0"); + exp1++; + } + + while(exp1 > exp2) + { + (void) strcat(man2,"0"); + exp2++; + } + + if (exp1 != exp2) /* boiler plate assertion */ + { + Z_fatal("mantissas didn't get lined up properly in floatsub"); + } + + (void) strcat(man1,R_getfrac(p1)); + (void) strcat(man2,R_getfrac(p2)); + + /* + ** now that the mantissa are aligned, + ** if the strings are the same, return 0 + */ + if((man_cmp_val = strcmp(man1,man2)) == 0) + { + R_setzero(result); + return(result); + } + + /* + ** pad the shorter string with 0's + ** when this loop finishes, both mantissas should + ** have the same length + */ + if (strlen(man1)> strlen(man2)) + { + addzeros(man2,strlen(man1)-strlen(man2)); + } + else + { + if (strlen(man1)=0;i--) + { + char from; + if (borrow) + { + if (big[i] == '0') + { + from = '9'; + } + else + { + from = big[i]-1; + borrow = 0; + } + } + else + { + if(big[i] R_getexp(f2)) + { + return(1); + } + + (void) strcpy(man1,R_getfrac(f1)); + S_trimzeros(man1); + + (void) strcpy(man2,R_getfrac(f2)); + S_trimzeros(man2); + return(strcmp(man1,man2)); + } + + F_float + F_floatmul(f1,f2) + F_float f1,f2; + { + static char prod[R_MANMAX]; + char *end; + int count1 = 0; + int count2 = 0; + int tmp,len; + char *end1; + char *end2; + static char man1[R_MANMAX],man2[R_MANMAX]; + char *bigman,*smallman; + static F_float result; + static int needinit = 1; + + if (needinit) + { + result = R_makefloat(); + needinit = 0; + } + /* + ** special case for a zero result + */ + if (R_zerofloat(f1) || R_zerofloat(f2)) + { + R_setzero(result); + return(result); + } + + (void) strcpy(man1,R_getfrac(f1)); + (void) strcpy(man2,R_getfrac(f2)); + + end1 = _F_GETEND(man1); + end2 = _F_GETEND(man2); + + /* + ** decide which number will cause multiplication loop to go + ** around the least + */ + while(end1 >= man1) + { + count1 += *end1 - '0'; + end1--; + } + + while(end2 >= man2) + { + count2 += *end2 - '0'; + end2--; + } + + + if (count1 > count2) + { + bigman = man1; + smallman = man2; + } + else + { + bigman = man2; + smallman = man1; + } + S_trimzeros(bigman); + S_trimzeros(smallman); + len = strlen(bigman) + strlen(smallman); + + end = _F_GETEND(smallman); + (void) strcpy(prod,"0"); + + /* + ** multiplication by repeated addition + */ + while(end >= smallman) + { + for(tmp = 0;tmp<*end-'0';tmp++) + { + _F_stradd(prod,bigman); + } + addzeros(bigman,1); + end--; + } + + R_setfrac(result,prod); + R_setexp(result,(((R_getexp(f1) + R_getexp(f2)) - len)+ strlen(prod))); + + if (R_getsign(f1) == R_getsign(f2)) + { + R_setsign(result,R_POSITIVE); + } + else + { + R_setsign(result,R_NEGATIVE); + } + return(result); + } + + _F_xor(x,y) + { + return(((x) && !(y)) || (!(x) && (y))); + } + #define _F_SAMESIGN(x,y) _F_xor((x<0),(y<0)) + #define _F_ABSADD(x,y) (Z_ABS(x) + Z_ABS(y)) + + _F_ABSDIFF(x,y) + { + if (Z_ABS(x) < Z_ABS(y)) + { + return(Z_ABS(y) - Z_ABS(x)); + } + else + { + return(Z_ABS(x) - Z_ABS(y)); + } + } + /* + ** add two floats without regard to sign + */ + F_float + F_floatmagadd(p1,p2) + F_float p1,p2; + { + static F_float result; + static int needinit = 1; + + static char man1[R_MANMAX],man2[R_MANMAX]; + + int digits; /* count of the number of digits needed to represent the + result */ + int resexp; /* exponent of the result */ + int len; /* length of the elements before adding */ + char *diffptr; + + if (needinit) + { + result = R_makefloat(); + needinit = 0; + } + (void) strcpy(man1,""); + (void) strcpy(man2,""); + + /* + ** find the difference in the exponents number of digits + */ + if( _F_SAMESIGN(R_getexp(p1),R_getexp(p2))) + { + digits = _F_ABSDIFF(R_getexp(p1),R_getexp(p2)); + } + else + { + digits = _F_ABSADD(R_getexp(p1),R_getexp(p2)); + } + + /* + ** make sure that there is room to store the result + */ + if (digits>0) + { + if (R_getexp(p1) < R_getexp(p2)) + { + /* + ** leave room for terminator + */ + if (digits+strlen(R_getfrac(p1)) > (R_MANMAX-1)) + { + (void) sprintf(Z_err_buf, + "numbers differ by too much in magnitude"); + Z_fatal(Z_err_buf); + } + } + else + { + /* + ** leave room for terminator + */ + if (digits+strlen(R_getfrac(p2)) > (R_MANMAX-1)) + { + (void) sprintf(Z_err_buf, + "numbers differ by too much in magnitude"); + Z_fatal(Z_err_buf); + } + } + } + else + { + /* + ** leave room for terminator and possible carry + */ + if (Z_MAX(strlen(R_getfrac(p1)), + strlen(R_getfrac(p2))) > (R_MANMAX-2)) + { + (void) sprintf(Z_err_buf, + "numbers differ by too much in magnitude"); + Z_fatal(Z_err_buf); + } + } + + /* + ** pad zeroes on the front of the smaller number + */ + if (R_getexp(p1) < R_getexp(p2)) + { + + addzeros(man1,digits); + resexp = R_getexp(p2); + } + else + { + addzeros(man2,digits); + resexp = R_getexp(p1); + } + (void) strcat(man1,R_getfrac(p1)); + (void) strcat(man2,R_getfrac(p2)); + + len = Z_MAX(strlen(man1),strlen(man2)); + + /* + ** add the two values + */ + _F_stradd(man1,man2); + + /* + ** adjust the exponent to account for a + ** possible carry + */ + resexp += strlen(man1) - len; + + + /* + ** trim the leading zeros on the sum + */ + diffptr = man1; + while('0' == *diffptr) + { + diffptr++; + resexp--; + } + + R_setfrac(result,diffptr); + R_setexp(result,resexp); + R_setsign(result,R_POSITIVE); + + return(result); + } + + /* + ** useful debugging routine. we don't call it in the release, + ** so it is commented out, but we'll leave it for future use + */ + + /* + F_printfloat(fl) + F_float fl; + { + (void) printf("fraction = :%s: exp = %d sign = %c\n", + R_getfrac(fl), + R_getexp(fl), + ((R_getsign(fl) == R_POSITIVE) ? '+': '-')); + + } + */ Index: llvm/utils/Spiff/float.h diff -c /dev/null llvm/utils/Spiff/float.h:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/float.h Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,35 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #include "floatrep.h" + + #ifndef F_INCLUDED + + /* + ** flags for F_atof + */ + #define NO_USE_ALL 0 + #define USE_ALL 1 + + typedef struct R_flstr *F_float; + #define F_getexp(x) R_getexp(x) + #define F_getsign(x) R_getsign(x) + #define F_zerofloat(x) R_zerofloat(x) + + extern F_float F_atof(); + + extern F_float F_floatmul(); + extern F_float F_floatmagadd(); + extern F_float F_floatsub(); + + #define F_null ((F_float) 0) + + #define F_INCLUDED + + #endif Index: llvm/utils/Spiff/floatrep.c diff -c /dev/null llvm/utils/Spiff/floatrep.c:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/floatrep.c Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,32 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef lint + static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/floatrep.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; + #endif + + #include "misc.h" + #include "floatrep.h" + + R_float + R_makefloat() + { + R_float retval; + + retval = Z_ALLOC(1,struct R_flstr); + retval->mantissa = Z_ALLOC(R_MANMAX,char); + return(retval); + } + + R_getexp(ptr) + R_float ptr; + { + return(ptr->exponent); + } + Index: llvm/utils/Spiff/floatrep.h diff -c /dev/null llvm/utils/Spiff/floatrep.h:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/floatrep.h Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,66 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + /* + ** header file that defines canonical floating point structure + ** and routines + */ + + + #ifndef R_INCLUDED + + /* + ** when evaluated to a string, the fractional part will + ** not exceed this length + */ + #define R_MANMAX 200 + + #define R_POSITIVE 0 + #define R_NEGATIVE 1 + + struct R_flstr { + int exponent; + int man_sign; + char *mantissa; + }; + + typedef struct R_flstr *R_float; + + #define R_getfrac(x) (x->mantissa) + + extern R_float R_makefloat(); + + extern int R_getexp(); + + #define R_getsign(x) (x->man_sign) + + /* + ** takes a string + */ + #define R_setfrac(x,y) ((void)strcpy(x->mantissa,y)) + /* + ** takes an int + */ + #define R_setexp(x,y) (x->exponent = y) + /* + ** takes a sign + */ + #define R_setsign(x,y) (x->man_sign = y) + + /* + #define R_incexp(x) ((x->exponent)++) + #define R_decexp(x) ((x->exponent)--) + */ + + #define R_setzero(x) R_setfrac(x,"0");R_setexp(x,0);R_setsign(x,R_POSITIVE) + + #define R_zerofloat(x) ((0 == x->exponent) && (!strcmp(x->mantissa,"0"))) + + #define R_INCLUDED + + #endif Index: llvm/utils/Spiff/line.c diff -c /dev/null llvm/utils/Spiff/line.c:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/line.c Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,169 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef lint + static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/line.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; + #endif + + #include + #include "misc.h" + #include "token.h" + #include "line.h" + + char *_L_al[_L_MAXLINES]; /* storage for lines */ + char *_L_bl[_L_MAXLINES]; + + int _L_ai[_L_MAXLINES]; /* index from token line number to first token */ + int _L_bi[_L_MAXLINES]; + + int _L_ac[_L_MAXLINES]; /* count of tokens on this token line */ + int _L_bc[_L_MAXLINES]; + + int _L_arlm; /* count of real lines in the file */ + int _L_brlm; + + int _L_aclm; /* count of content lines in the file */ + int _L_bclm; + + int _L_atlm; /* count of token lines in the file */ + int _L_btlm; + + int _L_aclindex[_L_MAXLINES]; /* mapping from content lines to real lines*/ + int _L_bclindex[_L_MAXLINES]; + + int _L_atlindex[_L_MAXLINES]; /*mapping from token lines to content lines */ + int _L_btlindex[_L_MAXLINES]; + + + static void + _L_setrline(file,X,str) + int file; + int X; + char *str; + { + if (file) + { + S_savestr(&_L_bl[X],str); + } + else + { + S_savestr(&_L_al[X],str); + } + return; + } + /* + ** returns 1 if we reached the end of file + ** returns 0 if there is more to do + ** + ** stores data and sets maximum counts + */ + L_init_file(fnumber,fname) + int fnumber; + char *fname; + { + extern char *fgets(); + FILE *fp; + static char buf[Z_LINELEN+2]; /* +2 is to leave room for us to add + a newline if we need to */ + int ret_val = 1; + int tmplen; + + if ((fp = fopen(fname,"r")) == (FILE*) NULL) + { + (void) sprintf(Z_err_buf, "Cannot open file %s.\n",fname); + Z_fatal(Z_err_buf); + } + + /* + ** clear the line count + */ + _L_setrlmx(fnumber,0); + + /* + ** read in the entire file + */ + while (fgets(buf,Z_LINELEN+1,fp) != (char *) NULL) + { + tmplen = strlen(buf); + if (tmplen <= 0) + { + (void) sprintf(Z_err_buf, + "fatal error -- got 0 length line %d in file %s\n", + L_getrlmax(fnumber)+1, + fname); + Z_fatal(Z_err_buf); + } + else if (tmplen > Z_LINELEN) + { + (void) sprintf(Z_err_buf, + "got fatally long line %d in file %s length is %d, must be a bug\n", + L_getrlmax(fnumber)+1, + fname,tmplen); + Z_fatal(Z_err_buf); + } + /* + ** look for newline as last character + */ + if ('\n' != buf[tmplen-1]) + { + /* + ** did we run out room in the buffer? + */ + if (tmplen == Z_LINELEN) + { + (void) sprintf(Z_err_buf, + "line %d too long in file %s, newline added after %d characters\n", + L_getrlmax(fnumber)+1, + fname,Z_LINELEN); + Z_complain(Z_err_buf); + } + else + { + (void) sprintf(Z_err_buf, + "didn't find a newline at end of line %d in file %s, added one\n", + L_getrlmax(fnumber)+1, + fname); + Z_complain(Z_err_buf); + } + + buf[tmplen] = '\n'; + buf[tmplen+1] = '\0'; + } + + _L_setrline(fnumber,L_getrlmax(fnumber),buf); + + if (L_getrlmax(fnumber) >= _L_MAXLINES-1) + { + (void) sprintf(Z_err_buf, + "warning -- ran out of space reading %s, truncated to %d lines\n", + fname,_L_MAXLINES); + Z_complain(Z_err_buf); + ret_val= 0; + break; + } + else + { + /* + ** increment the line count + */ + _L_incrlmx(fnumber); + } + + } + + (void) fclose(fp); + /* + ** reset line numbers + */ + L_setclmax(fnumber,0); + L_settlmax(fnumber,0); + + return(ret_val); + } + Index: llvm/utils/Spiff/line.h diff -c /dev/null llvm/utils/Spiff/line.h:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/line.h Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,113 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef L_INCLUDED + + #define _L_MAXLINES 10000 + + /* + ** oh god, is this an ugly implementation. + ** I really should have a two dimensional array of structures + ** the history of the current arrangement is too long + ** and ugly to record here. + ** Someday when I have too much time on my hands . . . + */ + + extern char *_L_al[]; /* storage for text in first file */ + extern char *_L_bl[]; /* storage for text in second file */ + + extern int _L_ai[]; /* pointer from token line to first token */ + extern int _L_bi[]; + + extern int _L_ac[]; /* number of tokens on a given token line */ + extern int _L_bc[]; + + extern int _L_aclindex[]; /* mapping from content lines to real lines */ + extern int _L_bclindex[]; + + extern int _L_atlindex[]; /* mapping from lines with tokens to content lines */ + extern int _L_btlindex[]; + + extern int _L_arlm; /* count of real lines */ + extern int _L_brlm; + + extern int _L_aclm; /* count of content lines */ + extern int _L_bclm; + + extern int _L_atlm; /* count of lines with tokens */ + extern int _L_btlm; + + /* + ** routines to set up mappings from token lines to content lines + ** and from content lines to real lines + */ + #define L_setclindex(file,content,real) (file?(_L_bclindex[content]=real):\ + (_L_aclindex[content]=real)) + + #define L_settlindex(file,token,content) (file?(_L_btlindex[token]=content):\ + (_L_atlindex[token]=content)) + /* + ** get line number X from file + */ + #define L_getrline(file, X) (file?(_L_bl[X]):(_L_al[X])) + #define L_getcline(file, X) (file?(_L_bl[_L_bclindex[X]]):\ + (_L_al[_L_aclindex[X]])) + #define L_gettline(file, X) (file?(_L_bl[_L_bclindex[_L_btlindex[X]]]):\ + (_L_al[_L_aclindex[_L_atlindex[X]]])) + + #define L_cl2rl(file, X) (file?(_L_bclindex[X]):\ + (_L_aclindex[X])) + #define L_tl2cl(file, X) (file?(_L_btlindex[X]):\ + (_L_atlindex[X])) + #define L_tl2rl(file, X) (file?(_L_bclindex[_L_btlindex[X]]):\ + (_L_aclindex[_L_atlindex[X]])) + + /* + ** get number of first token on line X of the file + */ + #define L_getindex(file,X) (file?(_L_bi[X]):(_L_ai[X])) + + /* + ** get count of number of tokens on line X of first file + */ + #define L_getcount(file,X) (file?(_L_bc[X]):(_L_ac[X])) + + /* + ** save number of first token for line X of file + */ + #define L_setindex(file,index,value) (file?(_L_bi[index]=value):(_L_ai[index]=value)) + /* + ** save count of tokens on line X of file + */ + #define L_setcount(file,index,value) (file?(_L_bc[index]=value):(_L_ac[index]=value)) + #define L_inccount(file,index) (file?(_L_bc[index]++):(_L_ac[index]++)) + + /* + ** retrieve line and token counts + */ + #define L_getrlmax(file) (file?_L_brlm:_L_arlm) + #define L_getclmax(file) (file?_L_bclm:_L_aclm) + #define L_gettlmax(file) (file?_L_btlm:_L_atlm) + + /* + ** set line and token counts + */ + #define _L_setrlmx(file,value) (file?(_L_brlm=(value)):(_L_arlm=(value))) + #define L_setclmax(file,value) (file?(_L_bclm=(value)):(_L_aclm=(value))) + #define L_settlmax(file,value) (file?(_L_btlm=(value)):(_L_atlm=(value))) + + /* + ** increment line and token counts + */ + #define _L_incrlmx(file) (file?(_L_brlm++):(_L_arlm++)) + #define L_incclmax(file) (file?(_L_bclm++):(_L_aclm++)) + #define L_inctlmax(file) (file?(_L_btlm++):(_L_atlm++)) + + #define L_INCLUDED + #endif Index: llvm/utils/Spiff/miller.c diff -c /dev/null llvm/utils/Spiff/miller.c:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/miller.c Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,127 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef lint + static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/miller.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; + #endif + + #include "misc.h" + #include "token.h" + #include "edit.h" + + #define MAXT K_MAXTOKENS + #define ORIGIN (max_obj/2) + + #define MILLER_CHATTER 100 + + /* + ** totally opaque miller/myers code + ** hacked from a version provided by the author + */ + + + E_edit + G_do_miller(m,n,max_d,comflags) + int m; + int n; + int max_d; + int comflags; + { + int max_obj = m + n; + int + lower, + upper, + d, + k, + row, + col; + E_edit new; + + #ifdef STATIC_MEM + static E_edit script[MAXT+1]; + static int last_d[MAXT+1]; + #else + E_edit *script; + int *last_d; + /* + ** make space for the two big arrays + ** these could probably be smaller if I + ** understood this algorithm at all + ** as is, i just shoe horned it into my program. + ** be sure to allocate max_obj + 1 objects as was done + ** in original miller/myers code + */ + script = Z_ALLOC(max_obj+1,E_edit); + last_d = Z_ALLOC(max_obj+1,int); + + #endif + for (row=0;row < m && row < n && X_com(row,row,comflags) == 0; ++row) + ; + last_d[ORIGIN] = row; + script[ORIGIN] = E_NULL; + lower = (row == m) ? ORIGIN+1 : ORIGIN - 1; + upper = (row == n) ? ORIGIN-1 : ORIGIN + 1; + if (lower > upper) + { + /* + ** the files are identical + */ + return(E_NULL); + } + for (d = 1; d <= max_d; ++d) { + for (k = lower; k<= upper; k+= 2) { + new = E_edit_alloc(); + + if (k == ORIGIN-d || k!= ORIGIN+d && last_d[k+1] >= last_d[k-1]) { + row = last_d[k+1]+1; + E_setnext(new,script[k+1]); + E_setop(new,E_DELETE); + } else { + row = last_d[k-1]; + E_setnext(new,script[k-1]); + E_setop(new,E_INSERT); + } + + E_setl1(new,row); + col = row + k - ORIGIN; + E_setl2(new,col); + script[k] = new; + + while (row < m && col < n && X_com(row,col,comflags) == 0) { + ++row; + ++col; + } + last_d[k] = row; + if (row == m && col == n) { + return(script[k]); + } + if (row == m) + lower = k+2; + if (col == n) + upper = k-2; + } + --lower; + ++upper; + #ifndef NOCHATTER + if ((d > 0) && (0 == (d % MILLER_CHATTER))) + { + (void) sprintf(Z_err_buf, + "found %d differences\n", + d); + Z_chatter(Z_err_buf); + } + #endif + } + Z_exceed(max_d); + /* + ** dummy lines to shut up lint + */ + Z_fatal("fell off end of do_miller\n"); + return(E_NULL); + } Index: llvm/utils/Spiff/miller.h diff -c /dev/null llvm/utils/Spiff/miller.h:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/miller.h Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,17 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + #ifndef G_INCLUDED + + #include "edit.h" + + extern E_edit G_do_miller(); + + #define G_INCLUDED + + #endif Index: llvm/utils/Spiff/misc.c diff -c /dev/null llvm/utils/Spiff/misc.c:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/misc.c Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,119 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef lint + static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/misc.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; + #endif + + #include + #include "misc.h" + #include "visual.h" + #include "output.h" + + /* + ** various routines used throughout the program + */ + + static int _Z_qflag = 0; + + void + Z_setquiet() + { + _Z_qflag = 1; + } + + char Z_err_buf[Z_LINELEN]; + + #ifndef NOCHATTER + /* + ** I/O coverup to reassure users with HUGE files + ** that spiff is doing something + */ + void + Z_chatter(str) + char *str; + { + if (!_Z_qflag) + { + (void) fputs("spiff -- ",stderr); + (void) fputs(str,stderr); + } + } + #endif + + /* + ** complain unless you've been told to be quiet + */ + void + Z_complain(str) + char *str; + { + if (!_Z_qflag) + (void) fputs(str,stderr); + } + + /* + ** quit with an error code + */ + static void + _Z_errexit() + { + (void) exit(2); + } + + /* + ** complain and die + */ + void + _Z_qfatal(str) + char *str; + { + V_cleanup(); /* try reset the device to normal */ + O_cleanup(); /* " " " " " " */ + Z_complain(str); + _Z_errexit(); + } + + /* + ** scream and die + */ + void + Z_fatal(str) + char *str; + { + V_cleanup(); /* try reset the device to normal */ + O_cleanup(); /* " " " " " " */ + (void) fputs(str,stderr); + _Z_errexit(); + } + + /* + ** allocate memory with error checking + */ + int* + _Z_myalloc(k) + int k; + { + int *tmp; + if (tmp = (int*) calloc((unsigned)k,(unsigned)1)) + { + return(tmp); + } + Z_fatal("Out of Memory\n"); + return(tmp); /* boilerplate to shut up lint */ + } + + void + Z_exceed(d) + int d; + { + (void) sprintf(Z_err_buf, + "The files differ in more than %d places\n", d); + _Z_qfatal(Z_err_buf); + } Index: llvm/utils/Spiff/misc.h diff -c /dev/null llvm/utils/Spiff/misc.h:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/misc.h Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,49 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + #ifndef Z_INCLUDED + + /* + ** make sure that if we have a XENIX system, that + ** we also treat it as an AT and T derivative + */ + #ifdef XENIX + #ifndef ATT + #define ATT + #endif + #endif + + #define Z_LINELEN 1024 + #define Z_WORDLEN 20 + + extern char Z_err_buf[]; + + /* + ** helpful macros + */ + #define Z_ABS(x) (( (x) < (0) )? (-(x)):(x)) + #define Z_MIN(x,y) (( (x) < (y) )? (x):(y)) + #define Z_MAX(x,y) (( (x) > (y) )? (x):(y)) + + #define Z_ALLOC(n,type) ((type*) _Z_myalloc((n) * sizeof (type))) + extern int *_Z_myalloc(); + + /* + ** lines needed to shut up lint + */ + + extern void Z_complain(); + extern void Z_fatal(); + extern void Z_exceed(); + extern void Z_setquiet(); + #ifndef NOCHATTER + extern void Z_chatter(); + #endif + + #define Z_INCLUDED + #endif Index: llvm/utils/Spiff/output.c diff -c /dev/null llvm/utils/Spiff/output.c:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/output.c Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,558 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef lint + static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/output.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; + #endif + + #include + + #ifdef M_TERMINFO + #include + #include + #endif + + #ifdef M_TERMCAP + #ifdef XENIX + #include + #endif + #endif + + #include "misc.h" + #include "flagdefs.h" + #include "edit.h" + #include "line.h" + #include "token.h" + + static int _O_need_init = 1; + static int _O_st_ok = 0; + static int _O_doing_ul = 0; + static char *_O_st_tmp; + #ifdef M_TERMCAP + static char _O_startline[Z_WORDLEN]; + static char _O_endline[Z_WORDLEN]; + #endif + + static void + _O_st_init() + { + char termn[Z_WORDLEN]; + #ifdef M_TERMCAP + static char entry[1024]; + #endif + + /* + ** see if standard out is a terminal + */ + if (!isatty(1)) + { + _O_need_init = 0; + _O_st_ok = 0; + return; + } + + if (NULL == (_O_st_tmp = (char*) getenv("TERM"))) + { + Z_complain("can't find TERM entry in environment\n"); + _O_need_init = 0; + _O_st_ok = 0; + return; + } + (void) strcpy(termn,_O_st_tmp); + + #ifdef M_TERMCAP + if (1 != tgetent(entry,termn)) + { + Z_complain("can't get TERMCAP info for terminal\n"); + _O_need_init = 0; + _O_st_ok = 0; + return; + } + + _O_st_tmp = _O_startline; + _O_startline[0] = '\0'; + tgetstr("so",&_O_st_tmp); + + _O_st_tmp = _O_endline; + _O_endline[0] = '\0'; + tgetstr("se",&_O_st_tmp); + + _O_st_ok = (strlen(_O_startline) > 0) && (strlen(_O_endline) > 0); + #endif + + #ifdef M_TERMINFO + setupterm(termn,1,&_O_st_ok); + #endif + _O_need_init = 0; + } + + void + O_cleanup() + { + /* + ** this probably isn't necessary, but in the + ** name of compeleteness. + */ + #ifdef M_TERMINFO + resetterm(); + #endif + } + + static void + _O_start_standout() + { + if (_O_need_init) + { + _O_st_init(); + } + if (_O_st_ok) + { + #ifdef M_TERMCAP + (void) printf("%s",_O_startline); + #endif + #ifdef M_TERMINFO + vidattr(A_STANDOUT); + #endif + } + else + { + _O_doing_ul = 1; + } + } + + static void + _O_end_standout() + { + if (_O_need_init) + { + _O_st_init(); + } + if (_O_st_ok) + { + #ifdef M_TERMCAP + (void) printf("%s",_O_endline); + #endif + #ifdef M_TERMINFO + vidattr(0); + #endif + } + else + { + _O_doing_ul = 0; + } + } + + static void + _O_pchars(line,start,end) + char *line; + int start,end; + { + int cnt; + + for(cnt=start;cnt < end; cnt++) + { + if (_O_doing_ul) + { + (void) putchar('_'); + (void) putchar('\b'); + } + (void) putchar(line[cnt]); + } + } + + + /* + ** convert a 0 origin token number to a 1 orgin token + ** number or 1 origin line number as appropriate + */ + static + _O_con_line(numb,flags,filenum) + int numb, flags,filenum; + { + if (flags & U_TOKENS) + { + return(numb+1); + } + else + { + /* + ** check to make sure that this is a real + ** line number. if not, then return 0 + ** on rare occasions, (i.e. insertion/deletion + ** of the first token in a file) we'll get + ** line numbers of -1. the usual look-up technique + ** won't work since we have no lines before than 0. + */ + if (numb < 0) + return(0); + /* + ** look up the line number the token and then + ** add 1 to make line number 1 origin + */ + return(L_tl2cl(filenum,numb)+1); + } + } + + static char * + _O_convert(ptr) + char *ptr; + { + static char spacetext[Z_WORDLEN]; + + if (1 == strlen(ptr)) + { + switch (*ptr) + { + default: + break; + case '\n' : + (void) strcpy(spacetext,""); + return(spacetext); + case '\t' : + (void) strcpy(spacetext,""); + return(spacetext); + case ' ' : + (void) strcpy(spacetext,""); + return(spacetext); + } + + } + return(ptr); + } + + static char* + _O_get_text(file,index,flags) + int file,index,flags; + { + static char buf[Z_LINELEN*2]; /* leave lots of room for both + the token text and the + chatter that preceeds it */ + char *text; + K_token tmp; + + if (flags & U_TOKENS) + { + tmp = K_gettoken(file,index); + text = _O_convert(K_gettext(tmp)); + (void) sprintf(buf,"%s -- line %d, character %d\n", + text, + /* + ** add 1 to make output start at line 1 + ** and character numbers start at 1 + */ + L_tl2cl(file,K_getline(tmp))+1, + K_getpos(tmp)+1); + return(buf); + } + else + { + return(L_gettline(file,index)); + } + } + #define _O_APP 1 + #define _O_DEL 2 + #define _O_CHA 3 + #define _O_TYPE_E 4 + + static void + _O_do_lines(start,end,file) + int start,end,file; + { + int cnt; + int lastline = -1; + int nextline; + K_token nexttoken; + for (cnt=start;cnt <= end; cnt++) + { + nexttoken = K_get_token(file,cnt); + nextline = K_getline(nexttoken); + if (lastline != nextline) + { + int lastone,lastchar; + K_token lasttok; + char linetext[Z_LINELEN+1]; /* leave room for + terminator */ + if (0 == file) + { + (void) printf("< "); + } + else + { + (void) printf("> "); + } + + /* + ** put loop here if you want to print + ** out any intervening lines that don't + ** have any tokens on them + */ + + /* + ** following line is necessary because + ** L_gettline is a macro, and can't be passed + */ + (void) strcpy(linetext,L_gettline(file,nextline)); + _O_pchars(linetext,0,K_getpos(nexttoken)); + _O_start_standout(); + /* + ** look for last token on this line to be + ** highlighted + */ + for ( lastone=cnt,lasttok = K_get_token(file,lastone); + (lastone<=end)&&(nextline == K_getline(lasttok)); + lastone++,lasttok = K_get_token(file,lastone)) + { + } + lastone--; + lasttok = K_get_token(file,lastone); + lastchar = K_getpos(lasttok) + + strlen(K_gettext(lasttok)); + _O_pchars(linetext,K_getpos(nexttoken),lastchar); + _O_end_standout(); + _O_pchars(linetext,lastchar,strlen(linetext)); + + lastline = nextline; + } + } + } + + void + O_output(start,flags) + E_edit start; + int flags; + { + int type = _O_TYPE_E; /* initialize to error state + ** this is to make sure that type is set + ** somewhere + */ + int t_beg1, t_beg2, t_end1, t_end2; /* token numbers */ + int first1, last1, first2, last2; + + E_edit ep, behind, ahead, a, b; + + /* + ** reverse the list of edits + */ + ahead = start; + ep = E_NULL; + while (ahead != E_NULL) { + /* + ** set token numbers intentionally out of range + ** as boilerplate + */ + t_beg1 = t_beg2 = t_end1 = t_end2 = -1; + /* + ** edit script is 1 origin, all of + ** our routines are zero origin + */ + E_setl1(ahead,(E_getl1(ahead))-1); + E_setl2(ahead,(E_getl2(ahead))-1); + + behind = ep; + ep = ahead; + ahead = E_getnext(ahead); + E_setnext(ep,behind); + } + + /* + ** now run down the list and collect the following information + ** type of change (_O_APP, _O_DEL or _O_CHA) + ** start and length for each file + */ + while (ep != E_NULL) + { + b = ep; + /* + ** operation always start here + */ + t_beg1 = E_getl1(ep); + /* + ** any deletions will appear before any insertions, + ** so, if the first edit is an E_INSERT, then this + ** this is an _O_APP + */ + if (E_getop(ep) == E_INSERT) + type = _O_APP; + else { + /* + ** run down the list looking for the edit + ** that is not part of the current deletion + */ + do { + a = b; + b = E_getnext(b); + } while ((b != E_NULL) && + (E_getop(b) == E_DELETE) && + ((E_getl1(b)) == ((E_getl1(a))+1))); + /* + ** if we have an insertion at the same place + ** as the deletion we just scanned, then + ** this is a change + */ + if ((b != E_NULL) && + ((E_getop(b)) == E_INSERT) && + ((E_getl1(b))==(E_getl1(a)))) + { + type = _O_CHA; + } + else + { + type = _O_DEL; + } + /* + ** set up start and length information for + ** first file + */ + t_end1 = E_getl1(a); + /* + ** move pointer to beginning of insertion + */ + ep = b; + /* + ** if we are showing only a deletion, + ** then we're all done, so skip ahead + */ + if (_O_DEL == type) + { + t_beg2 = E_getl2(a); + t_end2 = -1; /* dummy number, won't + ever be printed */ + + goto skipit; + } + } + t_beg2 = E_getl2(ep); + t_end2 = t_beg2-1; + /* + ** now run down the list lookingfor the + ** end of this insertion and keep count + ** of the number of times we step along + */ + do { + t_end2++; + ep = E_getnext(ep); + } while ((ep != E_NULL) && ((E_getop(ep)) == E_INSERT) && + ((E_getl1(ep)) == (E_getl1(b)))); + + skipit:; + if (flags & U_TOKENS) + { + /* + ** if we are dealing with tokens individually, + ** then just print then set printing so + */ + first1 = t_beg1; + last1 = t_end1; + first2 = t_beg2; + last2 = t_end2; + } + else + { + /* + ** we are printing differences in terms of lines + ** so find the beginning and ending lines of the + ** changes and print header in those terms + */ + if ( t_beg1 >= 0) + first1 = K_getline(K_get_token(0,t_beg1)); + else + first1 = t_beg1; + + if ( t_end1 >= 0) + last1 = K_getline(K_get_token(0,t_end1)); + else + last1 = t_end1; + + if ( t_beg2 >= 0) + first2 = K_getline(K_get_token(1,t_beg2)); + else + first2 = t_beg2; + + if ( t_end2 >= 0) + last2 = K_getline(K_get_token(1,t_end2)); + else + last2 = t_end2; + + } + /* + ** print the header for this difference + */ + (void) printf("%d",_O_con_line(first1,flags,0)); + switch (type) + { + case _O_APP : + (void) printf("a%d",_O_con_line(first2,flags,1)); + if (last2 > first2) + { + (void) printf(",%d",_O_con_line(last2,flags,1)); + } + (void) printf("\n"); + break; + case _O_DEL : + if (last1 > first1) + { + (void) printf(",%d",_O_con_line(last1,flags,0)); + } + (void) printf("d%d\n",_O_con_line(first2,flags,1)); + break; + case _O_CHA : + if (last1 > first1) + { + (void) printf(",%d",_O_con_line(last1,flags,0)); + } + (void) printf("c%d",_O_con_line(first2,flags,1)); + if (last2 > first2) + { + (void) printf(",%d",_O_con_line(last2,flags,1)); + } + (void) printf("\n"); + break; + default: + Z_fatal("type in O_output wasn't set\n"); + } + if (_O_DEL == type || _O_CHA == type) + { + if (flags & U_TOKENS) + { + int cnt; + for(cnt=first1;cnt <= last1; cnt++) + { + (void) printf("< %s", + _O_get_text(0,cnt,flags)); + } + } + else + { + _O_do_lines(t_beg1,t_end1,0); + } + } + if (_O_CHA == type) + { + (void) printf("---\n"); + } + if (_O_APP == type || _O_CHA == type) + { + if (flags & U_TOKENS) + { + int cnt; + for(cnt=first2;cnt <= last2; cnt++) + { + (void) printf("> %s", + _O_get_text(1,cnt,flags)); + } + } + else + { + _O_do_lines(t_beg2,t_end2,1); + } + } + } + O_cleanup(); + return; + } Index: llvm/utils/Spiff/output.h diff -c /dev/null llvm/utils/Spiff/output.h:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/output.h Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,17 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef O_INCLUDED + + extern void O_output(); + extern void O_cleanup(); + + #define O_INCLUDED + + #endif Index: llvm/utils/Spiff/paper.ms diff -c /dev/null llvm/utils/Spiff/paper.ms:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/paper.ms Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,819 ---- + .ll 6i + .nr PO 1.15i + .nr HM 0i + .nr FM 1.05i + .TL + SPIFF -- A Program for Making Controlled Approximate Comparisons of Files + .AU + Daniel Nachbar + .AI + Software Engineering Research Group + Bell Communications Research + Morristown, New Jersey + .AB + The well known program + .B + diff + .R + [1] + is inappropriate for some + common tasks such as comparing the output of floating + point calculations where roundoff errors + lead + .B + diff + .R + astray and comparing program source code + where some differences in the text (such as white space and comments) + have no effect on the operation of the compiled code. A new program, + named + .B + spiff, + .R + addresses these and other similar cases + by lexical parsing of the input files and then applying + a differencing algorithm to the token sequences. + .B + Spiff + .R + ignores differences + between floating point numbers that are below a user settable tolerance. + Other features include user settable commenting and literal string + conventions and a choice of differencing algorithm. + There is also an interactive mode wherein the input texts are displayed + with differences highlighted. The user can change numeric tolerances + "on the fly" and + .B + spiff + .R + will adjust the highlighting accordingly. + .AE + .SH + Some Troubles With Diff + .PP + Over the past several years, it has been fairly easy to tell when + a new type of computer arrived at a nearby computer center. + The best clue was the discordant chorus of + groaning, sighing, gnashing of teeth, pounding of foreheads on desks, + and other sounds of distress. Tracing these noises to their source, one + would find some poor soul in the process of installing + a numerical analysis package on the new machine. + .PP + One might expect that "moving up" to a new machine + would be a cause for celebration. + After all, new machines are typically bigger, faster, + and better than old machines. + However, the floating point arithmetic on any new machine is frequently + slightly different from any old machine. + As a consequence, + software package test routines produce output that is slightly different, + but still correct, on the new machines. + Serious troubles appear when the person installing the software package + attempts to compare the test output files from two different machines + by using a difference finding program such as + .B + diff. + .R + Programs such as + .B + diff + .R + do a character by character comparison. + .B + Diff + .R + finds a great many differences, most of which + are due to roundoff errors in the least significant digits of floating point + numbers. Others are the result of differences in the way + in which the two test runs + had printed a number (3.4e-1 vs. 0.34). + In one case, the test suite for the S statistical analysis package[2], + over 1700 floating point numbers are produced + (per machine). In the eyes of + .B + diff, + .R + roughly 1200 of these numbers are different. + However, none of the "differences" are important ones. + Nonetheless, software installers wind up inspecting the output by eye. + .PP + A similar problem arises when one attempts to + look for differences between two versions + of the same C program. + .B + Diff + .R + reports many differences that are not of interest. In + particular, white space (except inside quotation marks) and + anything inside a comment have no effect on the operation of the compiled + program and are usually not of interest. + .B + Diff + .R + does have a mode of operation where white space + within a line (spaces and tabs) can be ignored. + However, differences in the placement of newlines cannot be ignored. + This is particularly annoying since C programming + styles differ on whether to place a newline character before or after the '{' + characters that start blocks. + .SH + The Problem in General Terms + .PP + As already mentioned, programs such as + .B + diff + .R + do + a character-by-character comparison of the input files. + However, when it comes to interpreting + the contents of a file (either by a human or by a program) + it is almost never the case that characters + are treated individually. Rather, characters make up tokens such + as words and numbers, or act as separators between these tokens. + When comparing files, one is usually looking for + differences between these tokens, not the characters that make them up + or the characters that separate them. + .PP + What is needed is a program that first parses the input files + into tokens, and then applies a differencing algorithm to the token + sequences. + In addition to finding differences in terms of tokens, + it is possible to interpret the tokens and + compare different types of tokens in different ways. Numbers, for example, + can differ by a lot or a little.\** + .FS + Current differencing programs do not have such a notion because + the difference between two characters is a binary function. + Two characters are the same or they are not. + .FE + It is possible to use a tolerance when comparing two number tokens and + report only those differences that exceed the tolerance. + .SH + Design Issues + .PP + A serious design issue for such a program is how + complex to make the parse. The + .I + deeper + .R + one goes in the parsing the larger + the unit of text that can be manipulated. For instance, if one is looking + for differences in C code, a complete parse tree can be produced and + the differencing algorithm could examine insertion and deletion of entire + branches of the tree. However, deep parsing requires much more + complex parsing and slower differencing algorithms. + .PP + Another design issue is deciding how to interpret the tokens. + Closer interpretation may lead to greater flexibility in comparing tokens, but + also results in a more cumbersome and error-prone implementation. + .PP + In the program described here, we attempt to keep both the depth + of the parse and the semantics of the tokens to a minimum. + The parse is a simple + lexical parse with the input files broken up into one dimensional + sequences of numbers, literal strings and white space. + Literal strings and white space are not interpreted. Numbers + are treated as representing points on the real number line. + .SH + Default Operation + .PP + .B + Spiff\** + .R + .FS + We picked the name as a way to pay a small tribute to that famous intergalactic + adventurer Spaceman Spiff[3]. + .B + Spiff + .R + is also a contraction of "spiffy diff". + .FE + works very much like + .B + diff. + .R + It reads two files, looks + for differences, and prints a listing of the + differences in the form of + an edit script.\** + .FS + An edit script is a sequence of insertions and deletions + that will transform the first file into the second. + .FE + As already suggested, + .B + spiff + .R + parses the files into + literal strings and real numbers. + The definition of these tokens can be altered somewhat by the user + (more on this later). For now, suffice it + to say that literals are strings like "cow", "sit", + "into", etc. Real numbers look like "1.3", "1.6e-4" and so on. + All of the common formats for real numbers are recognized. + The only requirements for a string to be + treated as a real number is the presence + of a period and at least one digit. + By default, a string of digits without a decimal point + (such as "1988") is not considered to be a real number, + but rather a literal string.\** + Each non-alphanumeric character (such as #$@^&*) + is parsed into a separate literal token. + .FS + Integer numbers are often used as indices, labels, and so on. + Under these circumstances, it is more appropriate to treat them as literals. + Our choice of default was driven by a design goal + of having + .B + spiff + .R + be very conservative + when choosing to ignore differences. + .FE + .PP + Once + .B + spiff + .R + determines the two sequences of tokens, + it compares members of the first sequence with + members of the second sequence. + If two tokens are of different types, + .B + spiff + .R + deems them to be different, regardless of their content. + If both tokens are literal tokens, + .B + spiff + .R + will deem them + to be different if any of their characters differ. + When comparing two real numbers, + .B + spiff + .R + will deem them to be different only if + the difference in their values exceeds a user settable tolerance. + .SH + Altering Spiff's Operation + .PP + To make + .B + spiff + .R + more generally useful, the user can control: + .IP \(bu + how text strings are parsed into tokens + .IP \(bu + how tokens of the same type are compared + .IP \(bu + the choice of differencing algorithm used + .IP \(bu + and the granularity of edit considered by the differencing algorithm. + .LP + .PP + These features are described next. + .SH + Altering the Parse + .PP + The operation of the parser can be altered in several ways. + The user can specify that delimited sections of text are to be ignored + completely. This is useful for selectively ignoring the contents of + comments in programs. Similarly, the user can specify that + delimited sections of text (including white space) + be treated as a single literal token. So, literal strings in program + text can be treated appropriately. + Multiple sets of + delimiters may be specified at once (to handle cases such as the + Modula-2 programming language + where there are two ways to specify quoted strings). At present, + the delimiters must be fixed string (possibly restricted to the + beginning of the line) or end of line. + As a consequence of the mechanism for specifying literal strings, + multicharacter operators (such as the += operator in C) + can be parsed into a single token. + .PP + As yet, no provision is made for allowing delimiter + specification in terms of regular expressions. This omission + was made for the sake of simplifying the parser. + Nothing prevents the addition of regular expressions in the + future. However, the simple mechanism + already in place handles the literal string and commenting conventions + for most well known programming languages.\** + .FS + See the manual page in the appendix for examples of handling + C, Bourne Shell, Fortran, Lisp, Pascal, and Modula-2. The only + cases that are known not to work are comments in BASIC and + Hollerith strings in Fortran. + .FE + .PP + In addition to controlling literal string and comments, the user + may also specify whether to treat white space characters as any other + non-alphanumeric character (in other words, parse each white space + character into its own literal token), + whether to parse sign markers as part + of the number that they precede or as separate tokens, whether + to treat numbers without printed decimal markers (e.g. "1988") + as real numbers rather than as literal strings, and whether + to parse real numbers into literal tokens. + .SH + Altering the Comparison of Individual Tokens + .PP + As mentioned earlier, the user can set a tolerance below which differences + between real numbers are ignored. + .B + Spiff + .R + allows two kinds of tolerances: + absolute and relative. + Specifying an absolute tolerance will cause + .B + spiff + .R + to ignore differences + that are less than the specified value. + For instance, specifying an absolute tolerance of 0.01 will + cause only those differences greater than or equal to 0.01 to be reported. + Specifying a relative tolerance will cause + .B + spiff + .R + to ignore differences that are + smaller than some fraction of the number of larger magnitude. + Specifically, the value of the tolerance is interpreted + as a fraction of the larger (in absolute terms) + of the two floating point numbers being compared. + For example, + specifying a relative tolerance of 0.1 + will cause the two floating point numbers 1.0 and 0.91 to be deemed within + tolerance. The numbers 1.0 and 0.9 will be outside the tolerance. + Absolute and relative tolerances can be OR'ed together. In fact, + the most effective way to ignore differences that are due to roundoff errors + in floating point calculations is to use both + a relative tolerance (to handle limits in precision) as well as an absolute + tolerance (to handle cases when one number is zero and the other number is + almost zero).\** + .FS + All numbers differ from zero by 100% of their magnitude. Thus, to handle + numbers that are near zero, one would have to specify a relative tolerance + of 100% which would be unreasonably large when both numbers are non-zero. + .FE + In addition, the user can specify an infinite tolerance. This is useful + for checking the format of output while ignoring the actual numbers + produced. + .SH + Altering the Differencing Algorithm + .PP + By default, + .B + spiff + .R + produces a minimal edit sequence (using the Miller/Myers differencing algorithm[4]) + that will convert the first file into the second. + However, a minimal edit sequences is not always desirable. + For example, for the following two tables of numbers: + .DS + 0.1 0.2 0.3 0.2 0.3 0.4 + 0.4 0.5 0.6 0.5 0.6 0.7 + .DE + a minimal edit sequence to convert the table on + the left into the table on the right be to + would delete the first number (0.1) and insert 0.7 at the end.\** + .FS + The problem of having the elements of tables become misaligned when + the differencing algorithm is trying + to find a minimal number of edits can be reduced somewhat + by retaining newlines and not using tolerances. + Unfortunately, it does not go away. + .FE + Such a result, while logically correct, does not provide a good picture + of the differences between the two files. + In general, for text with a very definite structure (such as tables), + we may not want to consider insertions and deletions at all, but + only one-to-one changes.\** + .FS + A "change" can be expressed as one deletion and one insertion at the same + point in the text. + .FE + So, rather than look for a minimal edit script, we + merely want to compare each token in the first file with + the corresponding token in the second file. + .PP + The user can choose which differencing algorithm to use + (the default Miller/Myers or + the alternative one-to-one comparison) + based upon what is known about the input files. In general, + files produced mechanically + (such the output from test suites) have a very regular structure + and the one-to-one comparison works surprisingly well. + For files created by humans, the Miller/Myers + algorithm is more appropriate. + There is nothing in + .B + spiff's + .R + internal design that limits + the number of differencing algorithms that it can run. + Other differencing algorithms, + in particular the one used in + .B + diff, + .R + will probably be added later. + .SH + Altering the Granularity of the Edit Sequence + .PP + By default, + .B + spiff + .R + produces an edit sequence + in terms of insertions and deletions of individual tokens. + At times it may be more useful to + treat the contents of the files as tokens when looking for differences + but + express the edit script in terms of entire lines of the files rather + than individual tokens.\** + .FS + For instance, if one wants to have + .B + spiff + .R + produce output that can be fed into + the + .B + ed + .R + editor. + .FE + .B + Spiff + .R + provides a facility for restricting the edits to entire lines. + .SH + Treating Parts of the Files Differently + .PP + For complex input files, it is important that different parts of the + file be treated in different ways. In other words, it may be impossible + to find one set of parsing/differencing rules that work well for the + entire file. + .B + Spiff + .R + can differentiate between parts of the input files on two bases: + within a line and between lines. + Within a line, a different tolerance can be applied to each real number. + The tolerances are specified in terms of the ordinal position of the + numbers on the line (i.e. one tolerance is applied to the first real number + on each line, a different tolerance is applied to the second number on + each line, a third tolerance is applied to the third, and so on). If more + numbers appear on a line than there are tolerances specified, the last + tolerance is applied to all subsequent numbers on the line (i.e., if the user + specifies three tolerances, the third is applied to the third, fourth + fifth, . . . number on each line). This feature is useful for applying + different tolerances to the different columns of a table of numbers. + .PP + Between lines, the user can place "embedded commands" in the input files. + These commands + are instructions to parser that can change what tolerances are attached + to real numbers and the commenting and literal string conventions used by the + parser. Embedded commands are flagged to the parser + by starting the line with a user-specified + escape string. By combining within line and between line differentiation, + it is possible for the user to specify a different tolerance + for every single real number in the input files. + .SH + Visual Mode + .PP + So far, + .B + spiff's + .R + operation as an intelligent filter has been described. + .B + Spiff + .R + also has an interactive mode. + When operating in interactive mode, + .B + spiff + .R + places corresponding sections of the input files + side by side on user's screen.\** + .FS + Although the current implementation of + .B + spiff + .R + runs in many environments, + interactive mode works only under the MGR window manager.[5] + Other graphics interfaces will probably be added over time. + .FE + Tokens are compared using a one-to-one ordinal comparison, and any tokens that + are found to be different are highlighted in reverse video. + The user can interactively change the tolerances and + .B + spiff + .R + will alter the display + to reflect which real numbers exceed the new tolerances. + Other commands allow the user to page through the file and exit. + .SH + Performance + .PP + Two components of + .B + spiff, + .R + the parser and the differencing algorithm, + account for most of the execution time. Miller and Myers compare their + algorithm to the one used in the diff program. To restate their results, + the Miller/Myers algorithm is faster for files + that have relatively few differences but much + slower (quadratic time) for files with a great many differences. + .PP + For cases where the files do not differ greatly, + parsing the input files takes most of the time (around 80% of the total).\** + .FS + No effort has yet been made to make the parser run more quickly. + A faster parser could no doubt be written by generating a special state machine. + .FE + The performance of the parser is roughly similar to programs that do a similar + level of parsing (i.e. programs that must examine each character in the file). + For files where roughly half of the tokens are real numbers, + .B + spiff + .R + takes about twice as long to parse the input files + as an + .B + awk + .R + program that counts the number of words in a file:\** + .FS + For + .B + awk, + .R + a word is any string separated by white space. + .FE + .B + .DS + awk '{total += NF}' firstfile secondfile + .DE + .R + .PP + The time that it takes + .B + spiff + .R + to parse a file is substantially + increased if scanning is done for comments + and delimited literal strings. The precise effect depends upon the length of + the delimiters, whether they are restricted to appear at beginning of line, and + the frequency with which literals and comments appear in the input files. + As an example, adding the 12 literal conventions\** + .FS + One literal convention is for C literal strings. The rest enumerate multicharacter + operators. + .FE + and 1 commenting convention + required for C code roughly doubles the time required to parse input files.\** + .FS + So in total, it takes + .B + spiff + .R + about 4 times longer to parse a C program than it takes + .B + awk + .R + to count the number of words in the same file. + .FE + .PP + A more complete approach to evaluating + .B + spiff's + .R + performance must measure the total time that it takes for the user to complete a + differencing task. For example, consider one of the + test suites for the S statistical + analysis package mentioned at the beginning of this paper. + The output file for each machine is 427 lines long and contains + 1090 floating point numbers. It takes + .B + diff + .R + approximately 2 seconds on one of our "6 MIPS"\** computers + .FS + We will not comment on the usefulness of "MIPS" as a measure + of computing speed. The numbers provided are only intended to + give the reader some vague idea of how fast these programs run. + .FE + to compare the two files and produce + an edit script that is 548 lines long containing 1003 "differences" + in the floating point numbers. It takes the average tester + 5 minutes to print out the edit script and roughly 2 hours to examine + the output by hand to determine that the machines are, in fact, + both giving nearly identical answers. The total time needed is + 2 hours 5 minutes and 2 seconds. + .PP + In contrast, it takes + .B + spiff + .R + approximately 6 seconds on one of our "6 MIPS" computers to + produce an output file that is 4 lines long.\** + .FS + The output would be zero length except that the output of the + .B + time + .R + command is built into the S tests. + The timing information could easily be ignored using + .B + spiff's + .R + embedded commands. But, as we shall see, it hardly seems worth the trouble. + .FE + It takes the average tester 30 seconds to examine + .B + spiff's + .R + output. The total for + .B + spiff + .R + is 36 seconds. Therefore for this case, + .B + spiff + .R + will get the job done roughly 208.88 times faster than + .B + diff. + .R + .PP + In general, it is misleading to compare + .B + spiff's + .R + speed with that of + .B + diff. + .R + While both programs are looking for differences between files, + they operate on very different types of data (tokens vs. bytes). + An analogous comparison could be made between the speed of an assembler + and the speed of a C compiler. They are both language translators. + One runs much faster than the other. + None the less, most programmers use the slower program + whenever possible. + .SH + Using Spiff For Making Regression Tests Of Software + .PP + We envision + .B + spiff + .R + to be the first of several tools for aiding in the now + arduous task of making regression tests.\** + .FS + In software engineering parlance, a "regression test" is the process by + which a tester checks to make sure that the new version of a piece of + software still performs the same way as the older versions + on overlapping tasks. + .FE + Given + .B + spiff's + .R + current capabilities, the regression test designer can + take the output of an older version of software and through + the use of literal string and commenting conventions, + specify what parts of the output must remain identical and + what sections can change completely. By specifying tolerances, the test + designer can take into account how much of a difference in floating + point calculations is acceptable. + .PP + The test designer is also free to + edit the output from the older version of the software and add embedded + commands that can instruct + .B + spiff + .R + to treat various parts of the output + differently. The newly edited output can then serve as a template for + the output of later versions of the software. + .PP + Obviously, editing output by hand is a very low level mechanism for adding + specification information. It is our intention that + .B + spiff + .R + will become + the last element in a pipeline of programs. Programs (as yet unwritten) located + earlier in the pipeline + can implement a higher level representation of the specification information. + They read in the old and new input files, add the appropriate embedded commands, + and then pass the results to + .B + spiff + .R + which will do the actual differencing. + .SH + Future Work + .PP + There are many features that could be added to + .B + spiff + .R + (if there are not + too many already). Some of these include: + .IP \(bu + Using separate differencing algorithms on separate sections of the file + and/or limiting the scope of an edit sequence (fencing) + .IP \(bu + Providing a more general mechanism for specifying comments and literals + (perhaps allowing specification in terms of regular expressions). + As yet, we have not encountered any important cases where regular expressions + have been needed. Until such a case is encountered, we will leave regular + expressions out in the name of simplicity. + .IP \(bu + Allowing for a more general specification of what lines should look like. + At present, the user can only specify tolerances for numbers as a function + of their ordinal position on a line. The difficulty in expanding the + specification abilities of + .B + spiff + .R + is knowing when to stop. In the extreme, + we might add all of the functionality of a program such as + .B + awk.\** + .R + .FS + Imagine handling the case such as + "apply this tolerance to all numbers that appear + on a line starting with the word `foo' but only if the number is between 1.9 + and 3.6 and the word `bar' does not appear on the line". + .FE + We hope to keep + .B + spiff + .R + as simple as possible. Our first efforts in + this direction will try to implement higher level specification functions + outside of + .B + spiff. + .R + .SH + Acknowledgements + .PP + First and foremost, we thank Stu Feldman for his endless patience, constant encouragement + and numerous good ideas. We also extend thanks to Doug McIlroy for bringing the Miller/Myers + algorithm to our attention, Nat Howard for a key insight + and for his editorial comments + and Steve Uhler and Mike Bianchi for their editorial comments. + .SH + References + .IP [1] + Hunt,J.W. and M.D. McIlroy. + .I + An Algorithm For Differential File Comparisons, + .R + .B + Bell Labs Computer Science Technical Report, + .R + Number 41, 1975. + .IP [2] + Becker,R.A. and J.M. Chambers (1984). + .B + S \- An Interactive Environment For Data Analysis And + Graphics. + .R + Belmont, CA: Wadsworth Inc. + .IP [3] + Watterson, B. (1987). + .B + Calvin and Hobbes. + .R + New York: Andrews, McMeel & Parker. + .IP [4] + Miller, W. and E.W. Myers. + .I + A File Comparison Program, + .R + .B + Software \- + Practice and Experience + .R + 15, 11, 1025-1040, 1985. + .IP [5] + Uhler, S.A. + .I + MGR -- A Window Manager For UNIX, + .R + Sun User's Group Meeting. September 1986. + .LP Index: llvm/utils/Spiff/parse.c diff -c /dev/null llvm/utils/Spiff/parse.c:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/parse.c Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,802 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef lint + static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/parse.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; + #endif + + #include "misc.h" + #include "flagdefs.h" + #include "float.h" + #include "tol.h" + #include "token.h" + #include "line.h" + #include "command.h" + #include "comment.h" + #include "parse.h" + + + #include + + #define _P_PARSE_CHATTER 1000 + + + static int _P_realline; /* loop counter */ + static int _P_fnumb; + + static char *_P_nextchr; /* pointer to the next character to parse */ + static char *_P_firstchr; /* pointer to the beginning of the line being parsed */ + static int _P_next_tol; /* number of floats seen on this line */ + static int _P_stringsize; /* count of number of characters that are being + read into a comment or literal */ + static int _P_has_content; /* flag to indicate if the line being + parsed has any tokens on it */ + static int _P_start; /* first line to parse */ + static int _P_lcount; /* number of lines to parse */ + + static int _P_flags; /* location for global flags */ + + /* + ** by default, "words" can be made up of numbers and letters + ** the following code allows for extending the alphabet that can + ** be used in words. this is useful for handling languages such + ** as C where the underscore character is an allowable character + ** in an identifier. If a character (such as underscore) is NOT added + ** to the alphabet, the identifier will be broken into 2 or more "words" + ** by the parser. as such the two sequences + ** one_two + ** and + ** one _ two + ** would look identical to spiff. + */ + #define _P_ALPHALEN 256 + static char _P_alpha[_P_ALPHALEN]; + + static void + _P_alpha_clear() + { + *_P_alpha = '\0'; + } + + static + _P_in_alpha(chr) + char chr; + { + #ifndef ATT + extern int index(); + #endif + /* + ** special case when string terminator + ** is handed to us + */ + if ('\0' == chr) + return(0); + + #ifdef ATT + return((int) strchr(_P_alpha,chr)); + #else + return((int) index(_P_alpha,chr)); + #endif + } + + void + P_addalpha(ptr) + char *ptr; + { + char buf[Z_LINELEN]; + + S_wordcpy(buf,ptr); /* copy up to (but not including) + the first whitespace char */ + + if ((strlen(_P_alpha) + strlen(buf)) >= _P_ALPHALEN) + { + Z_fatal("too many characters added to extended alphabet"); + } + (void) strcat(_P_alpha,buf); + } + + /* + ** put parser in a default state + */ + + static char _P_dummyline[2]; /* a place to aim wild pointers */ + static void + _P_initparser() + { + _P_dummyline[0] = '\0'; + + /* + ** now reset all the state of each module + */ + C_clear_cmd(); /* disable embedded command key word */ + T_clear_tols(); + W_clearcoms(); + W_clearlits(); + _P_alpha_clear(); /* disable extended alphabet */ + + /* + ** and set state as defined by execute-time commands. + */ + C_docmds(); + return; + } + + + static + _P_needmore() + { + return(*_P_nextchr == '\0'); + } + + static + _P_nextline() + { + /* + ** if the line that we just finished had + ** some content, increment the count + */ + if (_P_has_content) + { + L_incclmax(_P_fnumb); + /* + ** if the previous line had a token + ** increment the line + */ + if (L_getcount(_P_fnumb,L_gettlmax(_P_fnumb))) + { + L_inctlmax(_P_fnumb); + L_setcount(_P_fnumb,L_gettlmax(_P_fnumb),0); + } + _P_has_content = 0; + } + + /* + ** reset the number of floats seen on the line + */ + _P_next_tol = 0; + + /* + ** get another line if there is one available + */ + _P_realline++; + if (_P_realline >= _P_start+_P_lcount) + { + return(1); + } + + _P_firstchr = _P_nextchr = L_getrline(_P_fnumb,_P_realline); + /* + ** and look for a command + */ + if (C_is_cmd(_P_firstchr)) + { + _P_nextchr = _P_dummyline; + _P_has_content = 0; + } + else + { + /* + ** we have a real line, so set up the index + */ + L_setclindex(_P_fnumb,L_getclmax(_P_fnumb),_P_realline); + _P_has_content = 1; + } + return(0); + } + + /* + ** the following three routines (_P_litsnarf, _P_bolsnarf, and _P_comsnarf + ** all do roughly the same thing. they scan ahead and collect the + ** specified string, move _P_nextchr to the end of the + ** comment or literal and return 1 if we run off the end of file, + ** 0 otherwise. it would have been nice to have 1 routine handle + ** all three task (there is much common code), however there were + ** so enough differences, (for instance, only comments check for nesting, + ** only literals need to set _P_stringsize, etc) + ** that I decided to split them up. + */ + static int + _P_litsnarf(litptr) + W_lit litptr; + { + _P_stringsize = 0; + /* + ** skip the start of literal string + */ + _P_nextchr += strlen(W_litbegin(litptr)); + _P_stringsize += strlen(W_litbegin(litptr)); + /* + ** is there a separate end string? + ** if not, then we're done + */ + if ('\0' == *(W_litend(litptr))) + { + return(0); + } + /* + ** loop once for each character in the literal + */ + while(1) + { + /* + ** if we are out of characters, move on to next line + */ + if (_P_needmore()) + { + if (_P_nextline()) + { + return(1); + } + if (!_P_has_content) + { + /* + ** since we've just gotten a command + ** check to see if this literal + ** is still legit ... + ** could have just been reset + ** by the command + */ + if (!W_is_lit(litptr)) + { + return(0); + } + } + } /* if _P_needmore */ + + /* + ** see if we have an escaped end of literal string + */ + if (('\0' != *(W_litescape(litptr))) && /* escape string exists */ + !S_wordcmp(_P_nextchr, + W_litescape(litptr)) && /* and escape matches */ + !S_wordcmp(_P_nextchr+strlen(W_litescape(litptr)), + W_litend(litptr))) /* and endstring matches */ + { + _P_nextchr += strlen(W_litescape(litptr)) + + strlen(W_litend(litptr)); + _P_stringsize += strlen(W_litescape(litptr)) + + strlen(W_litend(litptr)); + continue; + } + + /* + ** see if we have an end of literal string + */ + if (!S_wordcmp(_P_nextchr,W_litend(litptr))) /* escape matches */ + { + _P_nextchr += strlen(W_litend(litptr)); + _P_stringsize += strlen(W_litend(litptr)); + return(0); + } + /* + ** this must be yet another character in the literal, so + ** just snarf it up + */ + _P_nextchr++; + _P_stringsize++; + } /* while loop once for each character */ + + #ifndef lint + Z_fatal("shouldn't execute this line at the end of _P_litsnarf"); + #endif + } /* _P_litsnarf */ + + static int + _P_bolsnarf(bolptr) + W_bol bolptr; + { + /* + ** skip the start of comment string + */ + _P_nextchr += strlen(W_bolbegin(bolptr)); + /* + ** is there a separate end string + ** if not, then we're done + */ + if ('\0' == *(W_bolend(bolptr))) + { + return(0); + } + /* + ** loop once for each character in the comment + */ + while(1) + { + /* + ** if we are out of characters,move on to next line + */ + if (_P_needmore()) + { + if (_P_nextline()) + { + return(1); + } + if (!_P_has_content) + { + /* + ** since we've just gotten a command + ** check to see if this comment + ** is still legit ... comments + ** could have just been reset + ** by the command + */ + if (!W_is_bol(bolptr)) + { + return(0); + } + } + } /* if at end of line */ + + /* + ** see if we have an escaped end of comment string + */ + if ('\0' != *(W_bolescape(bolptr)) && /* escape string exists */ + !S_wordcmp(_P_nextchr, + W_bolescape(bolptr)) && /* and escape matches */ + !S_wordcmp(_P_nextchr+strlen(W_bolescape(bolptr)), + W_bolend(bolptr))) /* and end string matches */ + { + _P_nextchr += strlen(W_bolescape(bolptr)) + + strlen(W_bolend(bolptr)); + continue; + } + + /* + ** see if we have an end of comment string + */ + if (!S_wordcmp(_P_nextchr,W_bolend(bolptr))) + { + _P_nextchr += strlen(W_bolend(bolptr)); + return(0); + } + /* + ** this must be yet another character in the comment, so + ** just snarf it up + */ + _P_nextchr++; + } /* while loop once for each character */ + + #ifndef lint + Z_fatal("shouldn't execute this line in at end of _P_bolsnarf"); + #endif + } /* _P_bolsnarf */ + + /* + ** pass over a comment -- look for nexting + */ + static + _P_comsnarf(comptr) + W_com comptr; + { + int depth = 1; /* nesting depth */ + /* + ** skip the start of comment string + */ + _P_nextchr += strlen(W_combegin(comptr)); + + /* + ** is there a separate end string + ** if not, then we're done + */ + if ('\0' == *(W_comend(comptr))) + { + return(0); + } + /* + ** loop once for each character in the comment + */ + while(1) + { + /* + ** if we are out of characters, move on to next line + */ + if (_P_needmore()) + { + if (_P_nextline()) + { + return(1); + } + if (!_P_has_content) + { + /* + ** since we've just gotten a command + ** check to see if this comment + ** is still legit ... comments + ** could have just been reset + ** by the command + */ + if (!W_is_com(comptr)) + { + return(0); + } + } + } /* if at end of line */ + + /* + ** see if we have an escaped end of comment string + */ + if ('\0' != *(W_comescape(comptr)) && /* escape string exists */ + !S_wordcmp(_P_nextchr, + W_comescape(comptr)) && /* and escape matches */ + !S_wordcmp(_P_nextchr+strlen(W_comescape(comptr)), + W_comend(comptr))) /* and end string matches */ + { + /* + ** skip over the escape sequence and the end sequence + */ + _P_nextchr += strlen(W_comescape(comptr)) + + strlen(W_comend(comptr)); + continue; + } + + /* + ** see if we have an end of comment string + */ + if (!S_wordcmp(_P_nextchr,W_comend(comptr))) /* end matches */ + { + /* + ** skip over the end sequence + */ + _P_nextchr += strlen(W_comend(comptr)); + if (W_is_nesting(comptr)) + { + depth--; + if (0 == depth) + return(0); + } + else + { + return(0); + } + continue; + } + /* + ** see if we have another beginning of comment string + */ + if (W_is_nesting(comptr) && + !S_wordcmp(_P_nextchr,W_comend(comptr))) /* end matches */ + { + _P_nextchr += strlen(W_comend(comptr)); + depth++; + continue; + } + /* + ** this must be yet another character in the comment, so + ** just snarf it up + */ + _P_nextchr++; + } /* while loop once for each character */ + + #ifndef lint + Z_fatal("should not execute this line in _P_comsnarf\n"); + #endif + + } /* _P_comsnarf */ + + + /* + ** parse a file + */ + static void + _P_do_parse() + { + + char *ptr; /* scratch space */ + int tmp; + int ret_code; + + K_token newtoken; + W_bol bolptr; + W_com comptr; + W_lit litptr; + + int startline, endline, startpos; + + /* + ** main parsing loop + */ + while (1) + { + /* + ** get more text if necessary + */ + if (_P_needmore()) + { + if (_P_nextline()) + { + return; + } + + /* + ** if the line contains nothing of interest, + ** try again + */ + if (!_P_has_content) + { + continue; + } + + /* + ** check to see if this line starts a comment + */ + if ((bolptr = W_isbol(_P_firstchr)) != W_BOLNULL) + { + if (_P_bolsnarf(bolptr)) + { + return; + } + continue; + } + } /* if _P_needmore */ + + /* + ** skip whitespace + */ + if (!(U_INCLUDE_WS & _P_flags) && isspace(*_P_nextchr)) + { + _P_nextchr++; + continue; + } + + /* + ** check to see if this character starts a comment + */ + if ((comptr = W_iscom(_P_nextchr)) != W_COMNULL) + { + if (_P_comsnarf(comptr)) + { + return; + } + continue; + } + + /* + ** if there aren't any tokens on this line already + ** set up the index from the token line to the content line + */ + if (!L_getcount(_P_fnumb,L_gettlmax(_P_fnumb))) + { + L_settlindex(_P_fnumb, + L_gettlmax(_P_fnumb), + L_getclmax(_P_fnumb)); + /* + ** and the pointer from the token line to the + ** first token on the line + */ + L_setindex(_P_fnumb, + L_gettlmax(_P_fnumb), + K_gettmax(_P_fnumb)); + } + + startline = L_tl2cl(_P_fnumb,L_gettlmax(_P_fnumb)); + startpos = _P_nextchr-_P_firstchr; + + newtoken = K_maketoken(); + K_setline(newtoken,L_gettlmax(_P_fnumb)); + K_setpos(newtoken,startpos); + + ret_code = 0; + /* + ** check to see if this character starts a + ** delimited literal string + */ + if ((litptr = W_islit(_P_nextchr)) != W_LITNULL) + { + ret_code = _P_litsnarf(litptr); + K_settype(newtoken,K_LIT); + S_allocstr(&ptr,_P_stringsize); + /* + ** fixed nasty memory bug here by adding else + ** old code copied entire line even if literal + ** ended before the end of line + ** should check into getting strcpy loaded + ** locally + */ + endline = L_getclmax(_P_fnumb); + if (endline > startline) + { + /* + ** copy in the first line of the literal + */ + (void) strcpy(ptr, + L_getcline(_P_fnumb,startline) + +startpos); + /* + ** now copy all the lines between + ** the first and last + */ + for (tmp=startline+1;tmp + sets a limit on the total number of insertions and deletions + that will be considered. + If the files differ by more than the stated amount, + the program will give up, print a warning message, and exit. + .PP + The following options control the command script. More than one of + each may appear at at time. The commands accumulate. + .TP + .B \-f sfile + a command script to be taken from file + .IR sfile + .TP + .B \-s command-script + causes the following argument to be taken as a command script. + .PP + The following options control how individual objects are compared. + .TP + .B \-b + treat all objects (including floating point numbers) as literals. + .TP + .B \-c + ignore differences between upper and lower case. + .PP + The following commands will control how the files are parsed. + .TP + .B \-w + treat white space as objects. Each white space character will + be treated as a separate object when the program is comparing the + files. + .TP + .B \-m + treat leading sign characters ( + and \- ) as separate even + if they are followed by floating point numbers. + .TP + .B \-d + treat integer decimal numbers (such as 1987) as real numbers (subject to + tolerances) rather than as literal strings. + .PP + The following three flags are used to set the default tolerances. + The floating-point-numbers may be given in the formats accepted + by atof(3). + .TP + .B \-a floating-point-number + specifies an absolute value for the tolerance in floating point numbers. + The flag + .B \-a1e-2 + will cause all differences greater than 0.01 to be reported. + .TP + .B \-r floating-point-number + specifies a relative tolerance. The value given is interpreted + as a fraction of the larger (in absolute terms) + of the two floating point numbers being compared. + Thus, the flag + .B \-r0.1 + will cause the two floating point numbers 1.0 and 0.9 to be deemed within + tolerance. The numbers 1.0 and 0.89 will be outside the tolerance. + .TP + .B \-i + causes differences between floating point numbers to be ignored. + .PP + If more than one + .B \-a, \-r, + or + .B \-i + flag appear on the command line, + the tolerances will be OR'd together (i.e. any difference that is within + any of the tolerances will be ignored). + .PP + If no default tolerances is set on the command line, + the program will use a default tolerance of + .B '\-a 1e-10 \-r 1e-10'. + .SH SCRIPT COMMANDS + .PP + A script consists of commands, one per line. + Each command consists of a keyword possibly followed by arguments. + Arguments are separated by one or more tabs or spaces. + The commands are: + .TP + literal BEGIN-STRING [END-STRING [ESCAPE-STRING]] + Specifies the delimiters surrounding text that is to be treated as a single + literal object. If only one argument is present, then only that string itself is treated + as a literal. If only two arguments are present, they are taking as the starting + and ending delimiters respectively. If three arguments are present, they are treated + as the start delimiter, end delimiter, and a string that may be used to escape + an instance of the end delimiter. + .TP + beginchar BEGINNING-OF-LINE-CHARACTER + Set the the beginning of line character for BEGIN-STRING's in comments. + The default is '^'. + .TP + endchar END-OF-LINE-CHARACTER + Set the end of line character for END-STRING's in comments. + The default is '$'. + .TP + addalpha NEW-ALPHA-CHARACTER + Add NEW-ALPHA-CHARACTER to the set of characters allowed in literal strings. + By default, + .I spiff + parses sequences of characters that begin with a letter and followed by + zero or more letters or numbers as a single literal token. This definition + is overly restrictive when dealing with programming languages. + For example, in the C programming language, + the underscore character is allowed in identifiers. + .TP + comment BEGIN-STRING [END-STRING [ESCAPE-STRING]] + Specifies the delimiters surrounding text that is to be be ignored entirely + (i.e. viewed as comments). + The operation of the comment command is very similar to the literal command. + In addition, if the END-STRING consists of only + the end of line character, the end of line will delimit the end of the comment. + Also, if the BEGIN-STRING starts with the beginning of line character, only + lines that begin with the BEGIN-STRING will be ignored. + .PP + More than one comment specification and more than one literal string specification + may be specified at a time. + .TP + nestcom BEGIN-STRING [END-STRING [ESCAPE-STRING]] + Similar to the comment command, but allows comments to be nested. + Note, due to the design of the parser nested comments can not + have a BEGIN-STRING that starts with the beginning of line character. + .TP + resetcomments + Clears the list of comment specifications. + .TP + resetliterals + Clears the list of literal specifications. + .TP + tol [aVALUE\(brrVALUE\(bri\(brd . . . [ ; aVALUE\(brrVALUE\(bri\(brd . . . ] . . . ] + set the tolerance for floating point comparisons. + The arguments to the tol command are a set of tolerance specifications + separated by semicolons. If more than one a,r,d, or i appears within + a specification, then the tolerances are OR'd together (i.e. any difference + that is within any tolerance will be ignored). + The semantics of a,r, and i are identical to the + .B \-a, \-r, + and + .B \-i + flags. The d means that the default tolerance (as specified by the invocation + options) should be used. + If more than one specification appears on the line, the first + specification is applied to the first floating point number on each line, + the second specification to the second floating point number one each line + of the input files, and so on. If there are more floating point numbers + on a given line of input than tolerance specifications, + the last specification is used repeatedly for all remaining floating point numbers + on that line. + .TP + command STRING + lines in the input file that start with STRING will be interpreted as + command lines. If no "command" is given as part of a + .B \-s + or + .B \-f + then it will be impossible to embed commands in the input files. + .TP + rem + .TP + # + used to places human readable remarks into a commands script. Note that the + use of the '#' character differs from other command languages (for instance + the Bourne shell). + .I Spiff + will only recognize the '#' as beginning a comment when it is the first + non-blank character on the command line. A '#' character appearing elsewhere + will be treated as part of the command. Cautious users should use 'rem'. + Those hopelessly addicted to '#' as a comment character can have command + scripts with a familiar format. + .PP + Tolerances specified in the command scripts have precedence over the tolerance + specified on the invocation command line. The tolerance specified in + .I file1 + has precedence over the tolerance specified in + .I file2. + .PP + .SH VISUAL MODE + If + .I spiff + is invoked with the \-v option, it will enter an interactive mode rather + than produce an edit sequence. Three windows will be put on the screen. + Two windows will contain corresponding segments of the input files. + Objects that appear in both segments will be examined for differences and + if any difference is found, the objects will be highlighted in reverse video + on the screen. Objects that appear in only one window will have a line drawn + through them to indicate that they aren't being compared with anything in the other + text window. The third window is a command window. The command window will + accept a single tolerance specification (followed by a newline) + in a form suitable to the + .B tol + command. The tolerance specified will then be used as the default tolerance + and the display will be updated to highlight only those objects that exceed + the new default tolerance. Typing + .B m + (followed by a newline) will display the next screenfull of text. Typing + .B q + (followed by a newline) will cause the program to exit. + .SH LIMITS + Each input files can be no longer that 10,000 line long or contain more + than 50,000 tokens. Longer files will be truncated. + No line can be longer than 1024 characters. Newlines + will be inserted every 1024 character. + .SH EXAMPLES + .TP + spiff \-e \-d foo bar + this invocation (using exact match algorithm and treating integer numbers + as if they were floats) is very useful for examining large tables of numbers. + .TP + spiff \-0 foo bar + compare the two files, quitting after the first difference is found. + This makes the program operate roughly like cmp(1). + .TP + spiff \-0 -q foo bar + same as the above, but no output is produced. + The return code is still useful. + .TP + spiff \-w \-b foo bar + will make the program operate much like diff(1). + .TP + spiff \-a1e-5 \-r0.001 foo bar + compare the contents of the files foo and bar and ignore all differences between + floating point numbers that are less than or equal to + 0.00001 or 0.1% of the number of larger magnitude. + .TP + tol a.01 r.01 + will cause all differences between floating point numbers that are less than + or equal to + 0.01 or 1% of the number of larger magnitude to be ignored. + .TP + tol a.01 r.01 ; i + will cause the tolerance in the previous example to be applied to the first + floating point number on each line. All differences between the second and + subsequent floating point numbers on each line will be ignored. + .TP + tol a.01 r.01 ; i ; a.0001 + like the above except that only differences between the second floating point + number on each line will be ignored. The differences between + third and subsequent floating point numbers on each number will be ignored if they + are less than or equal to 0.0001. + .IP + A useful script for examing C code is: + .nf + literal " " \\ + comment /* */ + literal && + literal \(br\(br + literal <= + literal >= + literal != + literal == + literal -- + literal ++ + literal << + literal >> + literal -> + addalpha _ + tol a0 + .fi + .IP + A useful script for shell programs is: + .nf + literal ' ' \\ + comment # $ + tol a0 + .fi + .IP + A useful script for Fortran programs is: + .nf + literal ' ' ' + comment ^C $ + tol a0 + .fi + .IP + A useful script for Modula 2 programs is: + .nf + literal ' ' + literal " " + nestcom (* *) + literal := + literal <> + literal <= + literal >= + tol a0 + .fi + .IP + A useful script for Lisp programs is: + .nf + literal " " + comment ; $ + tol a0 + .fi + .SH DIAGNOSTICS + .I Spiff's + exit status is 0 if no differences are found, 1 if differences are found, and + 2 upon error. + .SH BUGS + In C code, escaped newlines will appear as differences. + .PP + Comments are treated as token delimiters. + .PP + Comments in Basic don't work right. The line number is not ignored. + .PP + Continuation lines in Fortran comments don't work. + .PP + There is no way to represent strings specified using a + Hollerith notation in Fortran. + .PP + In formated English text, hyphenated words, + movements in pictures, footnotes, etc. + will be reported as differences. + .PP + STRING's in script commands can not include whitespace. + .PP + Visual mode does not handle tabs properly. Files containing + tabs should be run through + expand(1) before trying to display them with visual mode. + .PP + In visual mode, the text windows appear in a fixed size and font. + Lines longer than the window size will not be handled properly. + .PP + Objects (literal strings) that contain newlines cause trouble in several places + in visual mode. + .PP + Visual mode should accept more than one tolerance specification. + .PP + When using visual mode or the exact match comparison algorithm, the program + should do the parsing on the fly rather than truncating long files. + .SH AUTHOR + Daniel Nachbar + .SH COPYRIGHT + .nf + Copyright (c) 1988 Bellcore + All Rights Reserved + Permission is granted to copy or use this program, + EXCEPT that it may not be sold for profit, the copyright + notice must be reproduced on copies, and credit should + be given to Bellcore where it is due. + BELLCORE MAKES NO WARRANTY AND ACCEPTS + NO LIABILITY FOR THIS PROGRAM. + .fi + + .br + .SH SEE ALSO + atof(3) + isatty(2) + diff(1) + cmp(1) + expand(1) + mgr(1L) + .PP + "Spiff -- A Program for Making Controlled Approximate Comparisons of Files", + by Daniel Nachbar. + .PP + "A File Comparison Program" by Webb Miller and Eugene W. Myers in Software \- + Practice and Experience, Volume 15(11), pp.1025-1040, (November 1985). Index: llvm/utils/Spiff/spiff.c diff -c /dev/null llvm/utils/Spiff/spiff.c:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/spiff.c Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,341 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef lint + static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/spiff.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; + #endif + + + #include + #include "misc.h" + #include "flagdefs.h" + #include "parse.h" + #include "edit.h" + #include "line.h" + #include "token.h" + #include "tol.h" + #include "command.h" + #include "compare.h" + #include "exact.h" + #include "miller.h" + #include "visual.h" + #include "output.h" + + extern void _Y_doargs(); + + static int _Y_eflag = 0; /* use exact match algorithm */ + static int _Y_vflag = 0; /* use visual mode */ + + /* + ** this is the set of flags that gets used throughout the top module + ** as well as being used to communicate between modules. + */ + static int _Y_flags; + + main(argc,argv) + int argc; + char *argv[]; + { + E_edit edit_end; + char *filename[2]; + + int max_d; /* max number of differences allowed */ + int i; /* loop counter */ + + /* + ** parse the command line + */ + _Y_doargs(argc,argv,&(filename[0]),&(filename[1]),&max_d); + + /* + ** initialize the default tolerance if it + ** hasn't been set already. + */ + T_initdefault(); + + /* + ** read and then parse the files + */ + + /* + ** L_initfile return a code that indicates if the + ** entire file was read or not + ** + ** P_fileparse also knows how to start at someplace other + ** than the first line of file + ** + ** Taken together, this is enough to do step our way + ** through the file using an exact match algorithm. + ** + ** Oh well, someday . . . + */ + for(i=0;i<=1;i++) + { + /* + ** read the file into core + */ + (void) L_init_file(i,filename[i]); + K_settmax(i,0); /* start tokens at 0 */ + /* + ** and parse the files into tokens + */ + P_file_parse(i,0,L_getrlmax(i),_Y_flags); + } + + if (_Y_vflag) + { + return(V_visual(_Y_flags)); + } + + /* + ** if max_d was not set on the command line + ** set it to be as large as is possible + ** since the most changes possible would + ** be to delete all the tokens in the + ** first file and add all the tokens from + ** the second, the max possible is the + ** sum of the number of tokens in the + ** two files. + */ + if (-1 == max_d) + max_d = K_gettmax(0) + K_gettmax(1); + + if (_Y_eflag) + { + edit_end = Q_do_exact(K_gettmax(0),K_gettmax(1), + max_d,_Y_flags); + } + else + { + edit_end = G_do_miller(K_gettmax(0), K_gettmax(1), + max_d,_Y_flags); + } + + if (E_NULL != edit_end) + { + O_output(edit_end,_Y_flags); + return(1); + } + return(0); + } + + /* + ** break a string into individual lines and feed + ** them to the command module + */ + static void + _Y_cmdlines(from) + char *from; + { + char buf[Z_LINELEN]; + char *to; + while ('\0' != *from) + { + /* + ** copy line into buf + */ + to = buf; + while (('\0' != *from) && ('\n' != *from)) + { + *to++ = *from++; + } + *to = '\0'; /* terminate the line */ + + /* + ** hand the line to the command module + */ + C_addcmd(buf); + /* + ** skip the newline + */ + if ('\n' == *from) + { + from++; + } + } + } + + /* + ** this useful macro handle arguements that are adjacent + ** to a flag or in the following word e.g -- + ** + ** -a XXX + ** and + ** -aXXX + ** + ** both work when SETPTR is used. + */ + #define SETPTR {if(strlen(argv[1]) == 2) {argv++;argc--;ptr=argv[1];}else ptr=(&argv[1][2]);} + + static void + _Y_doargs(argc,argv,file1,file2,max_d) + int argc; + char *argv[]; + char **file1,**file2; + int *max_d; + { + char *ptr; + + /* + ** mark maximum number of tokens as being unset + */ + *max_d = -1; + + while (argc > 1 && argv[1][0] == '-') + { + switch (argv[1][1]) + { + case 't': + _Y_flags |= U_TOKENS; + break; + case 'w': + _Y_flags |= U_INCLUDE_WS; + break; + + case 'b': + _Y_flags |= U_BYTE_COMPARE; + break; + + case 'c': + _Y_flags |= U_NO_CASE; + break; + case 'd' : + _Y_flags |= U_NEED_DECIMAL; + break; + case 'm' : + _Y_flags |= U_INC_SIGN; + break; + case 'a': + SETPTR; + T_defatol(ptr); + break; + case 'r': + SETPTR; + T_defrtol(ptr); + break; + case 'i': + T_defitol(); + break; + case 'e' : + _Y_eflag = 1; + break; + case 'v' : + _Y_vflag = 1; + break; + case 'q' : + Z_setquiet(); + break; + case 's' : + SETPTR; + _Y_cmdlines(ptr); + break; + case 'f' : + { + extern FILE *fopen(); + char buf[Z_LINELEN]; + FILE *cmdfile; + SETPTR; + if ((FILE*) NULL == + (cmdfile = fopen(ptr,"r"))) + { + Z_fatal("can't open command file\n"); + } + while ((char*) NULL != + (char*) fgets(buf,Z_LINELEN,cmdfile)) + { + C_addcmd(buf); + } + (void) fclose(cmdfile); + break; + } + /* + ** useful commands for + ** the C programming language + */ + case 'C' : + C_addcmd("literal \" \" \\ "); + C_addcmd("comment /* */ "); + C_addcmd("literal && "); + C_addcmd("literal || "); + C_addcmd("literal <= "); + C_addcmd("literal >= "); + C_addcmd("literal != "); + C_addcmd("literal == "); + C_addcmd("literal -- "); + C_addcmd("literal ++ "); + C_addcmd("literal << "); + C_addcmd("literal >> "); + C_addcmd("literal -> "); + C_addcmd("addalpha _ "); + C_addcmd("tol a0 "); + break; + /* + ** useful commands for + ** the Bourne shell programming language + */ + case 'S' : + C_addcmd("literal ' ' \\ "); + C_addcmd("comment # $ "); + C_addcmd("tol a0 "); + break; + /* + ** useful commands for + ** the Fortran programming language + */ + case 'F' : + C_addcmd("literal ' ' ' "); + C_addcmd("comment ^C $ "); + C_addcmd("tol a0 "); + break; + /* + ** useful commands for + ** the Lisp programming language + */ + case 'L' : + C_addcmd("literal \" \" "); + C_addcmd("comment ; $ "); + C_addcmd("tol a0 "); + break; + /* + ** useful commands for + ** the Modula-2 programming language + */ + case 'M' : + C_addcmd("literal ' ' "); + C_addcmd("literal \" \" "); + C_addcmd("comment (* *) "); + C_addcmd("literal := "); + C_addcmd("literal <> "); + C_addcmd("literal <= "); + C_addcmd("literal >= "); + C_addcmd("tol a0 "); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + *max_d = atoi(&argv[1][1]); + break; + default: + Z_fatal("don't understand arguments\n"); + } + ++argv; + --argc; + } + if (argc != 3) + Z_fatal ("spiff requires two file names.\n"); + *file1 = argv[1]; + *file2 = argv[2]; + } Index: llvm/utils/Spiff/strings.c diff -c /dev/null llvm/utils/Spiff/strings.c:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/strings.c Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,162 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef lint + static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/strings.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; + #endif + + #include + #include "misc.h" + #include "strings.h" + + /* + ** routines for handling strings. + ** several routines manipulate "words" + ** a "word" is a string not containing whitespace + */ + + /* + ** copy a single word. similar to strcpy + */ + void + S_wordcpy(to,from) + char *to, *from; + { + while ((*from != '\0') && isprint(*from) && (!isspace(*from))) + { + *to++ = *from++; + } + *to = '\0'; + return; + } + + /* + ** find the next whitespace character. The address of the pointer + ** is passed and the pointer itself is changed. + */ + void + S_skipword(theptr) + char **theptr; + { + while((**theptr != '\0') && isprint(**theptr) && (!isspace(**theptr))) + { + (*theptr)++; /* increment the pointer, NOT the pointer + to the pointer */ + } + return; + } + + /* + ** find the next non-whitespace character. The address of the pointer + ** is passed and the pointer itself is changed. + */ + void + S_skipspace(theptr) + char **theptr; + { + while((**theptr != '\0') && isspace(**theptr)) + { + (*theptr)++; /* increment the pointer, NOT the pointer + to the pointer */ + } + return; + } + + /* + ** move the pointer to the beginning of the next word + */ + void + S_nextword(theptr) + char **theptr; + { + S_skipword(theptr); + S_skipspace(theptr); + return; + } + + /* + ** see if the first string is a prefix of the second + ** returns 0 if yes + ** non zero if now + ** sigh -- the way strcmp does + */ + int + S_wordcmp(s1,s2) + char *s1,*s2; + { + return(strncmp(s1,s2,strlen(s2))); + } + + /* + ** chop off any trailing zeros on a string + ** but leave one zero if there are only zeros + */ + void + S_trimzeros(str) + char *str; + { + /* + ** end starts out pointing at the null terminator + */ + char *end = str + strlen(str); + + /* + ** if there is more than one character left in the string + */ + while(end > (str+1)) + { + --end; + if ('0' == *end) + { + *end = '\0'; + } + else + { + return; + } + } + return; + } + + /* + ** save a copy of the string + */ + void + S_savestr(to,from) + char **to,*from; + { + S_allocstr(to,strlen(from)); + (void) strcpy(*to,from); + return; + } + + /* + ** save cnt characters of the string + */ + void + S_savenstr(to,from,cnt) + char **to,*from; + { + S_allocstr(to,cnt); + (void) strncpy(*to,from,cnt); + *((*to)+cnt) = '\0'; + return; + } + + /* + ** allocate space for a string, add 1 to size to + ** make sure that there is room for the terminating null character + */ + void + S_allocstr(to,size) + char **to; + int size; + { + *to = Z_ALLOC(size+1,char); + } Index: llvm/utils/Spiff/strings.h diff -c /dev/null llvm/utils/Spiff/strings.h:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/strings.h Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,20 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + #ifndef S_INCLUDED + extern void S_wordcpy(); + extern void S_skipword(); + extern void S_skipspace(); + extern void S_nextword(); + extern int S_wordcmp(); + extern void S_trimzeros(); + extern void S_savestr(); + extern void S_savenstr(); + extern void S_allocstr(); + #define S_INCLUDED + #endif Index: llvm/utils/Spiff/token.c diff -c /dev/null llvm/utils/Spiff/token.c:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/token.c Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,37 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef lint + static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/token.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; + #endif + + #include "misc.h" + #include "token.h" + + K_token _K_ato[K_MAXTOKENS]; /* storage for tokens */ + K_token _K_bto[K_MAXTOKENS]; + + int _K_atm; + int _K_btm; + + void + K_settoken(file,index,pointer) + int file; + int index; + K_token pointer; + { + if (file) + { + _K_bto[index] = pointer; + } + else + { + _K_ato[index] = pointer; + } + } Index: llvm/utils/Spiff/token.h diff -c /dev/null llvm/utils/Spiff/token.h:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/token.h Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,81 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef K_INCLUDED + #include "float.h" + #include "tol.h" + #include "strings.h" + + #define K_MAXTOKENS 50000 + /* + ** values for token type + */ + #define K_LIT 1 + #define K_FLO_NUM 2 + + + typedef struct { + int linenum; /* line that the token started on */ + int pos; /* position on the line where token started */ + int type; /* token type */ + char *text; /* literal token text */ + /* + ** canonical floationg point representation + */ + F_float flo_num; + T_tol tolerance; + } _K_str, *K_token; + + /* + ** this should really be a two dimensional array + ** but i'm too lazy to recode it + */ + extern K_token _K_ato[]; /* storage for the tokens */ + extern K_token _K_bto[]; + /* + ** save token X from file + */ + extern void K_settoken(/*file,X,ptr*/); + #define K_gettoken(file, X) (file?(_K_bto[X]):(_K_ato[X])) + + extern int _K_atm; /* count of tokens */ + extern int _K_btm; + + /* + ** get token number X from file + */ + #define K_get_token(file, X) (file?(_K_bto[X]):(_K_ato[X])) + + #define K_gettmax(file) (file?_K_btm:_K_atm) + #define K_settmax(file,value) (file?(_K_btm=(value)):(_K_atm=(value))) + /* + ** increment and return true on overflow + */ + #define K_inctmax(file) ((file?(++_K_btm):(++_K_atm))>=K_MAXTOKENS) + + #define K_setline(x,y) (x->linenum = y) + #define K_setpos(x,y) (x->pos = y) + #define K_settext(x,y) (x->text = y) + #define K_savetext(x,y,z) S_savestr(&(x->text),y) + #define K_saventext(x,y,z) S_savenstr(&(x->text),y,z) + #define K_setfloat(x,y) (x->flo_num = y) + #define K_settol(x,y) (x->tolerance = y) + #define K_settype(x,y) (x->type = y) + + #define K_getline(x) (x->linenum) + #define K_getpos(x) (x->pos) + #define K_gettext(x) (x->text) + #define K_getfloat(x) (x->flo_num) + #define K_gettol(x) (x->tolerance) + #define K_gettype(x) (x->type) + + #define K_maketoken() (Z_ALLOC(1,_K_str)) + + #define K_INCLUDED + #endif Index: llvm/utils/Spiff/tol.c diff -c /dev/null llvm/utils/Spiff/tol.c:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/tol.c Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,361 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef lint + static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/tol.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; + #endif + + #include "misc.h" + #include "float.h" + #include "tol.h" + #include "token.h" + + /* + ** storage for the default tolerances + */ + T_tol _T_gtol = _T_null; + + /* + ** tolerances that can be set in the command script and attached to floating + ** point numbers at parse time + */ + static T_tol _T_tols[_T_TOLMAX]; + + /* + ** initialize the global tolerance + ** should be called only once at the beginning of the program + */ + void + T_initdefault() + { + static int called_before = 0; + + if (called_before) + { + Z_fatal("T_initdefault called more than once\n"); + } + + /* + ** if the default tolerance was set somewhere else + ** don't set it here + */ + if (T_isnull(_T_gtol)) + { + T_defatol(_T_ADEF); + T_defrtol(_T_RDEF); + } + called_before = 1; + } + + static void + _T_tolclear(addr) + T_tol *addr; + { + *addr = _T_null; + } + + /* + ** clear the parse time tolerances + */ + void + T_clear_tols() + { + int i; + for(i=0;i<_T_TOLMAX;i++) + { + _T_tolclear(&_T_tols[i]); + } + } + + static void + _T_defclear() + { + _T_tolclear(&_T_gtol); + } + + /* + ** take a series of specifiers and add them to the tolerance + */ + static void + _T_settol(toladdr,str) + T_tol *toladdr; + char *str; + { + char typechar; + while ('\0' != *str) + { + /* + ** find the first non-whitespace character + */ + S_skipspace(&str); + /* + ** snarf up the type specifier + */ + typechar = *str; + /* + ** now skip the first char + */ + str++; + /* + ** skip any possibly intervening whitespace + */ + S_skipspace(&str); + switch (typechar) + { + case 'a': + _T_addtol(toladdr,T_ABSOLUTE,str); + break; + case 'r': + _T_addtol(toladdr,T_RELATIVE,str); + break; + case 'i': + _T_addtol(toladdr,T_IGNORE,(char*)0); + break; + case 'd': + _T_appendtols(toladdr,_T_gtol); + break; + default: + (void) sprintf(Z_err_buf, + "don't understand tolerance type '%c'\n",typechar); + Z_fatal(Z_err_buf); + } + /* + ** and skip to next tolerance + */ + S_nextword(&str); + } + } + + /* + ** set the default tolerance + */ + void + T_setdef(str) + char *str; + { + _T_defclear(); + _T_settol(&_T_gtol,str); + } + + + static char* + _T_nextspec(ptr) + char *ptr; + { + /* + ** find the end of the current spec + */ + for(;(_T_SEPCHAR != *ptr) && ('\0' != *ptr);ptr++) + { + } + + /* + ** and step over the seperator if necessary + */ + if (_T_SEPCHAR == *ptr) + ptr++; + + return(ptr); + } + + /* + ** return just the next set of specs + ** ie the string up to end of line or + ** the first _T_SEPCHAR + ** returned string does not include the _T_SEPCHAR + */ + static char * + _T_getspec(from) + char *from; + { + static char retval[Z_LINELEN]; + char *ptr = retval; + + while((_T_SEPCHAR != *from) && ('\0' != *from)) + { + *ptr++ = *from++; + } + *ptr = '\0'; /* terminate the line */ + return(retval); + } + + /* + ** parse a series of _T_SEPCHAR separated tolerance specifications + */ + void + T_tolline(str) + char *str; + { + int nexttol; + + T_clear_tols(); + + for(nexttol=0;'\0' != *str;nexttol++,str = _T_nextspec(str)) + { + /* + ** make sure we haven't run off the end + */ + if (nexttol >= _T_TOLMAX) + { + Z_fatal("too many tolerances per line"); + } + + /* + ** and set the tolerance + */ + _T_settol(&_T_tols[nexttol],_T_getspec(str)); + } + } + + T_moretols(next_tol) + { + return((next_tol >= 0) && + (_T_TOLMAX-1 > next_tol) && + (!T_isnull( _T_tols[next_tol+1]))); + } + + T_tol + T_gettol(index) + int index; + { + return(_T_tols[index]); + } + + /* + ** chose which tolerance to use + ** precidence is + ** first tolerance + ** second tolerance + ** default tolerance + */ + T_tol + T_picktol(p1,p2) + T_tol p1, p2; + { + if (!(T_isnull(p1))) + return(p1); + + if (!(T_isnull(p2))) + return(p2); + + return(_T_gtol); + } + + void + _T_appendtols(to,from) + T_tol *to,from; + { + + T_tol last; + + /* + ** are there any elements on the list yet + */ + if (T_isnull(*to)) + { + /* + ** it's a null list, so allocat space for the + ** first element and set pointer to it. + */ + + *to = from; + } + else + { + /* + ** find the last element on the list + */ + for(last= *to;!T_isnull(T_getnext(last));last = T_getnext(last)) + { + } + /* + ** add an element on the end + */ + T_setnext(last,from); + } + } + + /* + ** add a tolerance to a list + */ + void + _T_addtol(listptr,type,str) + T_tol *listptr; + int type; + char *str; + { + T_tol last; + + /* + ** are there any elements on the list yet + */ + if (T_isnull(*listptr)) + { + /* + ** it's a null list, so allocat space for the + ** first element and set pointer to it. + */ + + last = *listptr = Z_ALLOC(1,_T_struct); + } + else + { + /* + ** find the last element on the list + */ + for(last= *listptr;!T_isnull(T_getnext(last));last = T_getnext(last)) + { + } + /* + ** add an element on the end + */ + T_setnext(last,Z_ALLOC(1,_T_struct)); + + /* + ** and point to the new element + */ + last = T_getnext(last); + } + + T_settype(last,type); + T_setnext(last,_T_null); + + /* + ** set the float value only if necessary + */ + if (T_IGNORE == type) + { + T_setfloat(last,F_null); + } + else + { + T_setfloat(last,F_atof(str,NO_USE_ALL)); + + /* + ** test new tolerance for sanity + */ + if (F_getsign(T_getfloat(last))) + { + (void) sprintf(Z_err_buf, + "%s : negative tolerances don't make any sense\n",str); + Z_fatal(Z_err_buf); + } + /* + ** check for excessively large relative tolerances + */ + if ((T_RELATIVE == type) && + (F_floatcmp(T_getfloat(last), + F_atof("2.0",USE_ALL)) > 0)) + { + (void) sprintf(Z_err_buf, + "%s : relative tolerances greater than 2 don't make any sense\n",str); + Z_fatal(Z_err_buf); + } + } + } Index: llvm/utils/Spiff/tol.h diff -c /dev/null llvm/utils/Spiff/tol.h:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/tol.h Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,64 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + #include "float.h" + + #ifndef T_INCLUDED + /* + ** values for tol_type + */ + #define T_ABSOLUTE 0 + #define T_RELATIVE 1 + #define T_IGNORE 2 + + typedef struct _T_tstr{ + int tol_type; /* one of the above */ + F_float flo_tol; /* tolerance is expressed in + terms of a floating point value */ + struct _T_tstr *next; + } _T_struct, *T_tol; + + #define _T_TOLMAX 10 /* number of tolerances that can + be in effect at one time */ + + #define _T_ADEF "1e-10" /* default absolute tolerance */ + #define _T_RDEF "1e-10" /* default relative tolerance */ + + extern T_tol T_gettol(); + extern void T_clear_tols(); + extern void T_initdefault(); + extern void T_setdef(); + extern void T_tolline(); + extern T_tol T_picktol(); + + #define T_gettype(x) (x->tol_type) + #define T_getfloat(x) (x->flo_tol) + #define T_getnext(x) (x->next) + + #define T_settype(x,y) (x->tol_type = y) + #define T_setfloat(x,y) (x->flo_tol = y) + #define T_setnext(x,y) (x->next = y) + + #define _T_null ((T_tol) 0) + #define T_isnull(x) ((x) == _T_null) + + extern T_tol _T_gtol; + extern void _T_addtol(); + extern void _T_appendtols(); + + /* + ** routines for building the global tolerance list + */ + #define T_defatol(x) _T_addtol(&_T_gtol,T_ABSOLUTE,x) + #define T_defrtol(x) _T_addtol(&_T_gtol,T_RELATIVE,x) + #define T_defitol() _T_addtol(&_T_gtol,T_IGNORE,(char*)NULL) + + #define _T_SEPCHAR ';' + + #define T_INCLUDED + #endif Index: llvm/utils/Spiff/visual.c diff -c /dev/null llvm/utils/Spiff/visual.c:1.1 *** /dev/null Mon Apr 12 17:53:34 2004 --- llvm/utils/Spiff/visual.c Mon Apr 12 17:53:24 2004 *************** *** 0 **** --- 1,411 ---- + /* Copyright (c) 1988 Bellcore + ** All Rights Reserved + ** Permission is granted to copy or use this program, EXCEPT that it + ** may not be sold for profit, the copyright notice must be reproduced + ** on copies, and credit should be given to Bellcore where it is due. + ** BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM. + */ + + + #ifndef lint + static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/visual.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; + #endif + + #ifdef MGR + + #include "misc.h" + #include "line.h" + #include "token.h" + #include "/usr/public/pkg/mgr/include/term.h" + #include "/usr/public/pkg/mgr/include/restart.h" + + #define OTHER 0 + #define ON_DEBUG 1 + #define OFF_DEBUG 2 + #define DO_QUIT 3 + #define DO_PAGE 4 + #define NEW_PREC 5 + + + #define NROW 60 + #define NCOL 80 + + int isdiff[MAXTOKENS]; /* flag showing if a token pair was shown different*/ + + int comwin,wina, winb; /* location to store window numbers */ + int fontx,fonty; /* size of the font in pixels */ + + int debug =0; + + + int firsttoken = 0; /* index of first token pair being displayed */ + int tokencnt; /* count of the number of token pairs being displayed */ + + V_visual(flags) + int flags; + { + + int moretodo = 1; /* flag to clear when we're finished */ + + messup(); + + m_selectwin(comwin); + m_setmode(W_ACTIVATE); + + showpages(comroutine,flags); + + do + { + switch(getinput()) + { + case ON_DEBUG: + debug = 0; + break; + case OFF_DEBUG: + debug = 1; + break; + case DO_QUIT: + moretodo = 0; + break; + case DO_PAGE: + if((firsttoken+tokencnt>= K_gettmax(0))|| + (firsttoken+tokencnt>= K_gettmax(1))) + { + m_selectwin(comwin); + m_printstr("\007this is the last page\n"); + break; + } + firsttoken += tokencnt; + showpages(comroutine,flags); + break; + case NEW_PREC: + updatepages(comroutine,flags); + break; + case OTHER: + break; + default : + Z_fatal("bad value in main switch"); + + } + } while (moretodo); + + V_cleanup(); + return(0); + } + + getinput() + { + char ibuf[Z_LINELEN]; /* input buffer */ + char *ptr; + + m_selectwin(comwin); + m_setmode(W_ACTIVATE); + switch (m_getchar()) + { + case 't': + m_gets(ibuf); + /* + ** skip the 'tol' + */ + ptr = ibuf; + S_nextword(&ptr); + T_setdef(ptr); + return(NEW_PREC); + case 'q': + return(DO_QUIT); + case 'd': + return(OFF_DEBUG); + case 'D': + return(ON_DEBUG); + case 'm': + return(DO_PAGE); + default: + return(OTHER); + } + + } + + showpages(comroutine,flags) + int (*comroutine)(); + int flags; + { + int i; + m_selectwin(wina); + m_clear(); + m_selectwin(winb); + m_clear(); + showlines(); + + for(i=firsttoken;ipos*fontx,fonty/2,(Bt[firsttoken]->pos*fontx)-2,fonty/2); + */ + } + + if (Anexttoken > Bnexttoken) + { + m_selectwin(wina); + for(i=Bnexttoken;i Changes in directory llvm/utils: Makefile updated: 1.4 -> 1.5 --- Log message: Build Spiff directory --- Diffs of the changes: (+1 -1) Index: llvm/utils/Makefile diff -u llvm/utils/Makefile:1.4 llvm/utils/Makefile:1.5 --- llvm/utils/Makefile:1.4 Mon Oct 20 17:29:13 2003 +++ llvm/utils/Makefile Mon Apr 12 17:53:51 2004 @@ -8,7 +8,7 @@ ##===----------------------------------------------------------------------===## LEVEL = .. -DIRS = Burg TableGen +DIRS = Burg TableGen Spiff include $(LEVEL)/Makefile.common From gaeke at cs.uiuc.edu Mon Apr 12 22:25:02 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Mon Apr 12 22:25:02 2004 Subject: [llvm-commits] CVS: llvm/utils/Spiff/comment.c comment.h compare.c exact.c float.c float.h floatrep.c line.c miller.c misc.c output.c parse.c spiff.c strings.c strings.h tol.c tol.h visual.c Message-ID: <200404130324.WAA31103@zion.cs.uiuc.edu> Changes in directory llvm/utils/Spiff: comment.c updated: 1.1 -> 1.2 comment.h updated: 1.1 -> 1.2 compare.c updated: 1.1 -> 1.2 exact.c updated: 1.1 -> 1.2 float.c updated: 1.1 -> 1.2 float.h updated: 1.1 -> 1.2 floatrep.c updated: 1.1 -> 1.2 line.c updated: 1.1 -> 1.2 miller.c updated: 1.1 -> 1.2 misc.c updated: 1.1 -> 1.2 output.c updated: 1.1 -> 1.2 parse.c updated: 1.1 -> 1.2 spiff.c updated: 1.1 -> 1.2 strings.c updated: 1.1 -> 1.2 strings.h updated: 1.1 -> 1.2 tol.c updated: 1.1 -> 1.2 tol.h updated: 1.1 -> 1.2 visual.c updated: 1.1 -> 1.2 --- Log message: Clean up the Spiff code so that it emits fewer warnings. This consists mostly of changing sloppy K&R C code to slightly more disciplined K&R C code, and doing the usual things to shut gcc up. --- Diffs of the changes: (+66 -26) Index: llvm/utils/Spiff/comment.c diff -u llvm/utils/Spiff/comment.c:1.1 llvm/utils/Spiff/comment.c:1.2 --- llvm/utils/Spiff/comment.c:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/comment.c Mon Apr 12 22:24:45 2004 @@ -8,7 +8,7 @@ #ifndef lint -static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/comment.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; +static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/comment.c,v 1.2 2004/04/13 03:24:45 gaeke Exp $"; #endif @@ -187,6 +187,7 @@ return(W_BOLNULL); } +int W_is_bol(ptr) W_bol ptr; { @@ -234,6 +235,7 @@ return(W_LITNULL); } +int W_is_lit(ptr) W_lit ptr; { @@ -281,6 +283,7 @@ return(W_COMNULL); } +int W_is_com(ptr) W_com ptr; { @@ -300,6 +303,7 @@ return(0); } +int W_is_nesting(ptr) W_com ptr; { Index: llvm/utils/Spiff/comment.h diff -u llvm/utils/Spiff/comment.h:1.1 llvm/utils/Spiff/comment.h:1.2 --- llvm/utils/Spiff/comment.h:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/comment.h Mon Apr 12 22:24:45 2004 @@ -66,6 +66,7 @@ extern int W_is_bol(); extern int W_is_lit(); extern int W_is_com(); +extern int W_is_nesting(); extern _W_bolstruct _W_bols[]; extern _W_litstruct _W_lits[]; Index: llvm/utils/Spiff/compare.c diff -u llvm/utils/Spiff/compare.c:1.1 llvm/utils/Spiff/compare.c:1.2 --- llvm/utils/Spiff/compare.c:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/compare.c Mon Apr 12 22:24:45 2004 @@ -8,7 +8,7 @@ #ifndef lint -static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/compare.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; +static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/compare.c,v 1.2 2004/04/13 03:24:45 gaeke Exp $"; #endif #include "misc.h" @@ -21,6 +21,11 @@ #include +static int _X_strcmp(); +static int _X_cmptokens(); +static int _X_floatdiff(); + +int X_com(a,b,flags) int a,b,flags; { Index: llvm/utils/Spiff/exact.c diff -u llvm/utils/Spiff/exact.c:1.1 llvm/utils/Spiff/exact.c:1.2 --- llvm/utils/Spiff/exact.c:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/exact.c Mon Apr 12 22:24:45 2004 @@ -8,11 +8,13 @@ #ifndef lint -static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/exact.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; +static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/exact.c,v 1.2 2004/04/13 03:24:45 gaeke Exp $"; #endif #include "misc.h" #include "edit.h" +#include "compare.h" +#include /* ** routine to compare each object with its ordinal twin Index: llvm/utils/Spiff/float.c diff -u llvm/utils/Spiff/float.c:1.1 llvm/utils/Spiff/float.c:1.2 --- llvm/utils/Spiff/float.c:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/float.c Mon Apr 12 22:24:45 2004 @@ -8,9 +8,11 @@ #ifndef lint -static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/float.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; +static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/float.c,v 1.2 2004/04/13 03:24:45 gaeke Exp $"; #endif +#include +#include #include #include "misc.h" #include "floatrep.h" @@ -37,6 +39,7 @@ ** returns 0 if string can't be interpreted as a float ** otherwise returns the number of digits that will be used in F_atof */ +int F_isfloat(str,need_decimal,allow_sign) char *str; int need_decimal; /* if non-zero, require that a decimal point be present @@ -367,7 +370,7 @@ F_float p1,p2; { static F_float result; - static needinit = 1; + static int needinit = 1; static char man1[R_MANMAX],man2[R_MANMAX],diff[R_MANMAX]; int exp1,exp2; char *diffptr,*big,*small; @@ -500,6 +503,7 @@ return(result); } +int F_floatcmp(f1,f2) F_float f1,f2; { @@ -645,14 +649,18 @@ return(result); } +int _F_xor(x,y) +int x, y; { return(((x) && !(y)) || (!(x) && (y))); } #define _F_SAMESIGN(x,y) _F_xor((x<0),(y<0)) #define _F_ABSADD(x,y) (Z_ABS(x) + Z_ABS(y)) +int _F_ABSDIFF(x,y) +int x, y; { if (Z_ABS(x) < Z_ABS(y)) { Index: llvm/utils/Spiff/float.h diff -u llvm/utils/Spiff/float.h:1.1 llvm/utils/Spiff/float.h:1.2 --- llvm/utils/Spiff/float.h:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/float.h Mon Apr 12 22:24:45 2004 @@ -27,6 +27,8 @@ extern F_float F_floatmul(); extern F_float F_floatmagadd(); extern F_float F_floatsub(); +extern int F_floatcmp(); +extern int F_isfloat(); #define F_null ((F_float) 0) Index: llvm/utils/Spiff/floatrep.c diff -u llvm/utils/Spiff/floatrep.c:1.1 llvm/utils/Spiff/floatrep.c:1.2 --- llvm/utils/Spiff/floatrep.c:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/floatrep.c Mon Apr 12 22:24:45 2004 @@ -8,7 +8,7 @@ #ifndef lint -static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/floatrep.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; +static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/floatrep.c,v 1.2 2004/04/13 03:24:45 gaeke Exp $"; #endif #include "misc.h" @@ -24,6 +24,7 @@ return(retval); } +int R_getexp(ptr) R_float ptr; { Index: llvm/utils/Spiff/line.c diff -u llvm/utils/Spiff/line.c:1.1 llvm/utils/Spiff/line.c:1.2 --- llvm/utils/Spiff/line.c:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/line.c Mon Apr 12 22:24:45 2004 @@ -8,7 +8,7 @@ #ifndef lint -static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/line.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; +static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/line.c,v 1.2 2004/04/13 03:24:45 gaeke Exp $"; #endif #include @@ -63,6 +63,7 @@ ** ** stores data and sets maximum counts */ +int L_init_file(fnumber,fname) int fnumber; char *fname; Index: llvm/utils/Spiff/miller.c diff -u llvm/utils/Spiff/miller.c:1.1 llvm/utils/Spiff/miller.c:1.2 --- llvm/utils/Spiff/miller.c:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/miller.c Mon Apr 12 22:24:45 2004 @@ -8,12 +8,14 @@ #ifndef lint -static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/miller.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; +static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/miller.c,v 1.2 2004/04/13 03:24:45 gaeke Exp $"; #endif +#include #include "misc.h" #include "token.h" #include "edit.h" +#include "compare.h" #define MAXT K_MAXTOKENS #define ORIGIN (max_obj/2) @@ -78,7 +80,7 @@ for (k = lower; k<= upper; k+= 2) { new = E_edit_alloc(); - if (k == ORIGIN-d || k!= ORIGIN+d && last_d[k+1] >= last_d[k-1]) { + if (k == ORIGIN-d || (k!= ORIGIN+d && last_d[k+1] >= last_d[k-1])) { row = last_d[k+1]+1; E_setnext(new,script[k+1]); E_setop(new,E_DELETE); Index: llvm/utils/Spiff/misc.c diff -u llvm/utils/Spiff/misc.c:1.1 llvm/utils/Spiff/misc.c:1.2 --- llvm/utils/Spiff/misc.c:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/misc.c Mon Apr 12 22:24:45 2004 @@ -8,13 +8,14 @@ #ifndef lint -static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/misc.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; +static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/misc.c,v 1.2 2004/04/13 03:24:45 gaeke Exp $"; #endif #include #include "misc.h" #include "visual.h" #include "output.h" +#include /* ** various routines used throughout the program @@ -101,7 +102,7 @@ int k; { int *tmp; - if (tmp = (int*) calloc((unsigned)k,(unsigned)1)) + if ((tmp = (int*) calloc((unsigned)k,(unsigned)1))) { return(tmp); } Index: llvm/utils/Spiff/output.c diff -u llvm/utils/Spiff/output.c:1.1 llvm/utils/Spiff/output.c:1.2 --- llvm/utils/Spiff/output.c:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/output.c Mon Apr 12 22:24:45 2004 @@ -8,10 +8,12 @@ #ifndef lint -static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/output.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; +static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/output.c,v 1.2 2004/04/13 03:24:45 gaeke Exp $"; #endif #include +#include +#include #ifdef M_TERMINFO #include @@ -171,7 +173,7 @@ ** convert a 0 origin token number to a 1 orgin token ** number or 1 origin line number as appropriate */ -static +static int _O_con_line(numb,flags,filenum) int numb, flags,filenum; { Index: llvm/utils/Spiff/parse.c diff -u llvm/utils/Spiff/parse.c:1.1 llvm/utils/Spiff/parse.c:1.2 --- llvm/utils/Spiff/parse.c:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/parse.c Mon Apr 12 22:24:45 2004 @@ -8,7 +8,7 @@ #ifndef lint -static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/parse.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; +static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/parse.c,v 1.2 2004/04/13 03:24:45 gaeke Exp $"; #endif #include "misc.h" @@ -21,7 +21,6 @@ #include "comment.h" #include "parse.h" - #include #define _P_PARSE_CHATTER 1000 @@ -64,7 +63,7 @@ *_P_alpha = '\0'; } -static +static int _P_in_alpha(chr) char chr; { @@ -128,13 +127,13 @@ } -static +static int _P_needmore() { return(*_P_nextchr == '\0'); } -static +static int _P_nextline() { /* @@ -370,7 +369,7 @@ /* ** pass over a comment -- look for nexting */ -static +static int _P_comsnarf(comptr) W_com comptr; { @@ -640,9 +639,9 @@ /* ** see if this is a floating point number */ - else if (tmp = F_isfloat(_P_nextchr, + else if ((tmp = F_isfloat(_P_nextchr, _P_flags & U_NEED_DECIMAL, - _P_flags & U_INC_SIGN)) + _P_flags & U_INC_SIGN))) { K_saventext(newtoken,_P_nextchr,tmp); K_settype(newtoken,K_FLO_NUM); Index: llvm/utils/Spiff/spiff.c diff -u llvm/utils/Spiff/spiff.c:1.1 llvm/utils/Spiff/spiff.c:1.2 --- llvm/utils/Spiff/spiff.c:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/spiff.c Mon Apr 12 22:24:45 2004 @@ -8,11 +8,12 @@ #ifndef lint -static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/spiff.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; +static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/spiff.c,v 1.2 2004/04/13 03:24:45 gaeke Exp $"; #endif #include +#include #include "misc.h" #include "flagdefs.h" #include "parse.h" @@ -27,7 +28,10 @@ #include "visual.h" #include "output.h" -extern void _Y_doargs(); +extern int L_init_file(); +extern int V_visual(); + +static void _Y_doargs(); static int _Y_eflag = 0; /* use exact match algorithm */ static int _Y_vflag = 0; /* use visual mode */ @@ -38,6 +42,7 @@ */ static int _Y_flags; +int main(argc,argv) int argc; char *argv[]; Index: llvm/utils/Spiff/strings.c diff -u llvm/utils/Spiff/strings.c:1.1 llvm/utils/Spiff/strings.c:1.2 --- llvm/utils/Spiff/strings.c:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/strings.c Mon Apr 12 22:24:45 2004 @@ -8,7 +8,7 @@ #ifndef lint -static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/strings.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; +static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/strings.c,v 1.2 2004/04/13 03:24:45 gaeke Exp $"; #endif #include @@ -142,6 +142,7 @@ void S_savenstr(to,from,cnt) char **to,*from; +int cnt; { S_allocstr(to,cnt); (void) strncpy(*to,from,cnt); Index: llvm/utils/Spiff/strings.h diff -u llvm/utils/Spiff/strings.h:1.1 llvm/utils/Spiff/strings.h:1.2 --- llvm/utils/Spiff/strings.h:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/strings.h Mon Apr 12 22:24:45 2004 @@ -7,6 +7,7 @@ */ #ifndef S_INCLUDED +#include extern void S_wordcpy(); extern void S_skipword(); extern void S_skipspace(); Index: llvm/utils/Spiff/tol.c diff -u llvm/utils/Spiff/tol.c:1.1 llvm/utils/Spiff/tol.c:1.2 --- llvm/utils/Spiff/tol.c:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/tol.c Mon Apr 12 22:24:45 2004 @@ -8,9 +8,10 @@ #ifndef lint -static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/tol.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; +static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/tol.c,v 1.2 2004/04/13 03:24:45 gaeke Exp $"; #endif +#include #include "misc.h" #include "float.h" #include "tol.h" @@ -213,7 +214,9 @@ } } +int T_moretols(next_tol) +int next_tol; { return((next_tol >= 0) && (_T_TOLMAX-1 > next_tol) && Index: llvm/utils/Spiff/tol.h diff -u llvm/utils/Spiff/tol.h:1.1 llvm/utils/Spiff/tol.h:1.2 --- llvm/utils/Spiff/tol.h:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/tol.h Mon Apr 12 22:24:45 2004 @@ -35,6 +35,7 @@ extern void T_setdef(); extern void T_tolline(); extern T_tol T_picktol(); +extern int T_moretols(); #define T_gettype(x) (x->tol_type) #define T_getfloat(x) (x->flo_tol) Index: llvm/utils/Spiff/visual.c diff -u llvm/utils/Spiff/visual.c:1.1 llvm/utils/Spiff/visual.c:1.2 --- llvm/utils/Spiff/visual.c:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/visual.c Mon Apr 12 22:24:45 2004 @@ -8,7 +8,7 @@ #ifndef lint -static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/visual.c,v 1.1 2004/04/12 22:53:24 gaeke Exp $"; +static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/visual.c,v 1.2 2004/04/13 03:24:45 gaeke Exp $"; #endif #ifdef MGR @@ -396,6 +396,7 @@ ** dummy code for systems that don't have ** the mgr window manager installed */ +int V_visual(d) int d; { From lattner at cs.uiuc.edu Tue Apr 13 00:06:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 00:06:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopSimplify.cpp Message-ID: <200404130505.AAA31617@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopSimplify.cpp updated: 1.39 -> 1.40 --- Log message: This patch addresses PR35: http://llvm.cs.uiuc.edu/PR35 : Loop simplify should reconstruct nested loops. This is fairly straight-forward, but was a real nightmare to get just perfect. aarg. :) --- Diffs of the changes: (+196 -6) Index: llvm/lib/Transforms/Scalar/LoopSimplify.cpp diff -u llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.39 llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.40 --- llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.39 Thu Apr 1 13:21:46 2004 +++ llvm/lib/Transforms/Scalar/LoopSimplify.cpp Tue Apr 13 00:05:33 2004 @@ -41,6 +41,7 @@ #include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Support/CFG.h" +#include "llvm/Transforms/Utils/Local.h" #include "Support/SetOperations.h" #include "Support/Statistic.h" #include "Support/DepthFirstIterator.h" @@ -49,6 +50,8 @@ namespace { Statistic<> NumInserted("loopsimplify", "Number of pre-header or exit blocks inserted"); + Statistic<> + NumNested("loopsimplify", "Number of nested loops split out"); struct LoopSimplify : public FunctionPass { virtual bool runOnFunction(Function &F); @@ -72,6 +75,7 @@ const std::vector &Preds); void RewriteLoopExitBlock(Loop *L, BasicBlock *Exit); void InsertPreheaderForLoop(Loop *L); + Loop *SeparateNestedLoop(Loop *L); void InsertUniqueBackedgeBlock(Loop *L); void UpdateDomInfoForRevectoredPreds(BasicBlock *NewBB, @@ -159,10 +163,17 @@ } } - // The preheader may have more than two predecessors at this point (from the - // preheader and from the backedges). To simplify the loop more, insert an - // extra back-edge block in the loop so that there is exactly one backedge. + // If the header has more than two predecessors at this point (from the + // preheader and from multiple backedges), we must adjust the loop. if (L->getNumBackEdges() != 1) { + // If this is really a nested loop, rip it out into a child loop. + if (Loop *NL = SeparateNestedLoop(L)) { + ++NumNested; + // This is a big restructuring change, reprocess the whole loop. + ProcessLoop(NL); + return true; + } + InsertUniqueBackedgeBlock(L); NumInserted++; Changed = true; @@ -198,8 +209,9 @@ // Check to see if the values being merged into the new block need PHI // nodes. If so, insert them. for (BasicBlock::iterator I = BB->begin(); - PHINode *PN = dyn_cast(I); ++I) { - + PHINode *PN = dyn_cast(I); ) { + ++I; + // Check to see if all of the values coming in are the same. If so, we // don't need to create a new PHI node. Value *InVal = PN->getIncomingValueForBlock(Preds[0]); @@ -216,7 +228,7 @@ // Move all of the edges from blocks outside the loop to the new PHI for (unsigned i = 0, e = Preds.size(); i != e; ++i) { - Value *V = PN->removeIncomingValue(Preds[i]); + Value *V = PN->removeIncomingValue(Preds[i], false); NewPHI->addIncoming(V, Preds[i]); } InVal = NewPHI; @@ -230,6 +242,12 @@ // Add an incoming value to the PHI node in the loop for the preheader // edge. PN->addIncoming(InVal, NewBB); + + // Can we eliminate this phi node now? + if (Value *V = hasConstantValue(PN)) { + PN->replaceAllUsesWith(V); + BB->getInstList().erase(PN); + } } // Now that the PHI nodes are updated, actually move the edges from @@ -382,6 +400,9 @@ } } +/// RewriteLoopExitBlock - Ensure that the loop preheader dominates all exit +/// blocks. This method is used to split exit blocks that have predecessors +/// outside of the loop. void LoopSimplify::RewriteLoopExitBlock(Loop *L, BasicBlock *Exit) { DominatorSet &DS = getAnalysis(); assert(std::find(L->getExitBlocks().begin(), L->getExitBlocks().end(), Exit) @@ -408,6 +429,175 @@ // Update dominator information (set, immdom, domtree, and domfrontier) UpdateDomInfoForRevectoredPreds(NewBB, LoopBlocks); } + +/// AddBlockAndPredsToSet - Add the specified block, and all of its +/// predecessors, to the specified set, if it's not already in there. Stop +/// predecessor traversal when we reach StopBlock. +static void AddBlockAndPredsToSet(BasicBlock *BB, BasicBlock *StopBlock, + std::set &Blocks) { + if (!Blocks.insert(BB).second) return; // already processed. + if (BB == StopBlock) return; // Stop here! + + for (pred_iterator I = pred_begin(BB), E = pred_end(BB); I != E; ++I) + AddBlockAndPredsToSet(*I, StopBlock, Blocks); +} + +static void ReplaceExitBlocksOfLoopAndParents(Loop *L, BasicBlock *Old, + BasicBlock *New) { + if (!L->hasExitBlock(Old)) return; + L->changeExitBlock(Old, New); + ReplaceExitBlocksOfLoopAndParents(L->getParentLoop(), Old, New); +} + +/// VerifyExitBlocks - This is a function which can be useful for hacking on the +/// LoopSimplify Code. +static void VerifyExitBlocks(Loop *L) { + std::vector ExitBlocks; + for (unsigned i = 0, e = L->getBlocks().size(); i != e; ++i) { + BasicBlock *BB = L->getBlocks()[i]; + for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI) + if (!L->contains(*SI)) + ExitBlocks.push_back(*SI); + } + + std::vector EB = L->getExitBlocks(); + std::sort(EB.begin(), EB.end()); + std::sort(ExitBlocks.begin(), ExitBlocks.end()); + assert(EB == ExitBlocks && "Exit blocks were incorrectly updated!"); + + for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I) + VerifyExitBlocks(*I); +} + +/// SeparateNestedLoop - If this loop has multiple backedges, try to pull one of +/// them out into a nested loop. This is important for code that looks like +/// this: +/// +/// Loop: +/// ... +/// br cond, Loop, Next +/// ... +/// br cond2, Loop, Out +/// +/// To identify this common case, we look at the PHI nodes in the header of the +/// loop. PHI nodes with unchanging values on one backedge correspond to values +/// that change in the "outer" loop, but not in the "inner" loop. +/// +/// If we are able to separate out a loop, return the new outer loop that was +/// created. +/// +Loop *LoopSimplify::SeparateNestedLoop(Loop *L) { + BasicBlock *Header = L->getHeader(); + + std::vector OuterLoopPreds; + for (BasicBlock::iterator I = Header->begin(); + PHINode *PN = dyn_cast(I); ) { + ++I; + if (Value *V = hasConstantValue(PN)) { + // This is a degenerate PHI already, don't modify it! + PN->replaceAllUsesWith(V); + Header->getInstList().erase(PN); + continue; + } + + // Scan this PHI node looking for a use of the PHI node by itself. + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) + if (PN->getIncomingValue(i) == PN && + L->contains(PN->getIncomingBlock(i))) { + // Wow, we found something tasty to remove. Pull out all predecessors + // that have varying values in the loop. This handles the case when a + // PHI node has multiple instances of itself as arguments. + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) + if (PN->getIncomingValue(i) != PN || + !L->contains(PN->getIncomingBlock(i))) + OuterLoopPreds.push_back(PN->getIncomingBlock(i)); + goto FoundExtraction; + } + } + + return 0; // Nothing looks appetizing to separate out + +FoundExtraction: + BasicBlock *NewBB = SplitBlockPredecessors(Header, ".outer", OuterLoopPreds); + + // Update dominator information (set, immdom, domtree, and domfrontier) + UpdateDomInfoForRevectoredPreds(NewBB, OuterLoopPreds); + + // Create the new outer loop. + Loop *NewOuter = new Loop(); + + LoopInfo &LI = getAnalysis(); + + // Change the parent loop to use the outer loop as its child now. + if (Loop *Parent = L->getParentLoop()) + Parent->replaceChildLoopWith(L, NewOuter); + else + LI.changeTopLevelLoop(L, NewOuter); + + // This block is going to be our new header block: add it to this loop and all + // parent loops. + NewOuter->addBasicBlockToLoop(NewBB, getAnalysis()); + + // L is now a subloop of our outer loop. + NewOuter->addChildLoop(L); + + // Add all of L's exit blocks to the outer loop. + for (unsigned i = 0, e = L->getExitBlocks().size(); i != e; ++i) + NewOuter->addExitBlock(L->getExitBlocks()[i]); + + // Add temporary exit block entries for NewBB. Add one for each edge in L + // that goes to NewBB. + for (pred_iterator PI = pred_begin(NewBB), E = pred_end(NewBB); PI != E; ++PI) + if (L->contains(*PI)) + L->addExitBlock(NewBB); + + for (unsigned i = 0, e = L->getBlocks().size(); i != e; ++i) + NewOuter->addBlockEntry(L->getBlocks()[i]); + + // Determine which blocks should stay in L and which should be moved out to + // the Outer loop now. + DominatorSet &DS = getAnalysis(); + std::set BlocksInL; + for (pred_iterator PI = pred_begin(Header), E = pred_end(Header); PI!=E; ++PI) + if (DS.dominates(Header, *PI)) + AddBlockAndPredsToSet(*PI, Header, BlocksInL); + + + // Scan all of the loop children of L, moving them to OuterLoop if they are + // not part of the inner loop. + for (Loop::iterator I = L->begin(); I != L->end(); ) + if (BlocksInL.count((*I)->getHeader())) + ++I; // Loop remains in L + else + NewOuter->addChildLoop(L->removeChildLoop(I)); + + // Now that we know which blocks are in L and which need to be moved to + // OuterLoop, move any blocks that need it. + for (unsigned i = 0; i != L->getBlocks().size(); ++i) { + BasicBlock *BB = L->getBlocks()[i]; + if (!BlocksInL.count(BB)) { + // Move this block to the parent, updating the exit blocks sets + L->removeBlockFromLoop(BB); + if (LI[BB] == L) + LI.changeLoopFor(BB, NewOuter); + --i; + } + } + + // Check all subloops of this loop, replacing any exit blocks that got + // revectored with the new basic block. + for (pred_iterator I = pred_begin(NewBB), E = pred_end(NewBB); I != E; ++I) + if (NewOuter->contains(*I)) { + // Change any exit blocks that used to go to Header to go to NewBB + // instead. + ReplaceExitBlocksOfLoopAndParents((Loop*)LI[*I], Header, NewBB); + } + + //VerifyExitBlocks(NewOuter); + return NewOuter; +} + + /// InsertUniqueBackedgeBlock - This method is called when the specified loop /// has more than one backedge in it. If this occurs, revector all of these From criswell at cs.uiuc.edu Tue Apr 13 08:44:02 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue Apr 13 08:44:02 2004 Subject: [llvm-commits] CVS: llvm/LICENSE.TXT Message-ID: <200404131342.IAA28058@choi.cs.uiuc.edu> Changes in directory llvm: LICENSE.TXT updated: 1.14 -> 1.15 --- Log message: Added Spiff. --- Diffs of the changes: (+1 -0) Index: llvm/LICENSE.TXT diff -u llvm/LICENSE.TXT:1.14 llvm/LICENSE.TXT:1.15 --- llvm/LICENSE.TXT:1.14 Tue Apr 6 15:23:45 2004 +++ llvm/LICENSE.TXT Tue Apr 13 08:42:38 2004 @@ -66,6 +66,7 @@ llvm/projects/sample/autoconf Burg: llvm/utils/Burg llvm/test/Programs/MultiSource/Applications/Burg +Spiff: llvm/utils/Spiff Aha: llvm/test/Programs/MultiSource/Applications/aha SGEFA: llvm/test/Programs/MultiSource/Applications/sgefa SIOD: llvm/test/Programs/MultiSource/Applications/siod From lattner at cs.uiuc.edu Tue Apr 13 08:58:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 08:58:02 2004 Subject: [llvm-commits] CVS: llvm/runtime/Makefile Message-ID: <200404131357.IAA28653@zion.cs.uiuc.edu> Changes in directory llvm/runtime: Makefile updated: 1.14 -> 1.15 --- Log message: Temporary hack to get the nightly tester running --- Diffs of the changes: (+1 -1) Index: llvm/runtime/Makefile diff -u llvm/runtime/Makefile:1.14 llvm/runtime/Makefile:1.15 --- llvm/runtime/Makefile:1.14 Fri Feb 27 11:00:29 2004 +++ llvm/runtime/Makefile Tue Apr 13 08:57:29 2004 @@ -12,7 +12,7 @@ include $(LEVEL)/Makefile.config ifneq ($(wildcard $(LLVMGCCDIR)),) -PARALLEL_DIRS := GCCLibraries libdummy libprofile libtrace libpng zlib +PARALLEL_DIRS := GCCLibraries libdummy libprofile libtrace libpng else PARALLEL_DIRS := install all :: From lattner at cs.uiuc.edu Tue Apr 13 09:44:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 09:44:02 2004 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200404131443.JAA01632@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.162 -> 1.163 --- Log message: Add notes about some of the code quality improvements that have gone in --- Diffs of the changes: (+27 -3) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.162 llvm/docs/ReleaseNotes.html:1.163 --- llvm/docs/ReleaseNotes.html:1.162 Tue Apr 6 14:48:42 2004 +++ llvm/docs/ReleaseNotes.html Tue Apr 13 09:43:35 2004 @@ -127,8 +127,32 @@
        -
      1. [vmcore] Code quality problem due to long operand of getelementptr
      2. -
      3. The X86 backend now generates substantially better code for 64-bit integer operations.
      4. +
      5. [vmcore] Code quality problem due to +long operand of getelementptr
      6. + +
      7. The X86 backend now generates substantially better code for 64-bit integer +and floating point operations.
      8. + +
      9. The -inline pass no longer inlines mutually recursive functions until it +hits the inlining threshold.
      10. + +
      11. The -inline pass no longer misses obvious inlining opportunities just +because the callee eventually calls into an external function.
      12. + +
      13. The -simplifycfg pass can now "if convert" simple statements into the new +select instruction.
      14. + +
      15. The -loopsimplify pass can now break natural loops with multiple backedges +into multiple nested loops. This enables a variety of subsequent +optimizations.
      16. + +
      17. The -adce pass can now eliminate calls to functions that do not not write to +memory.
      18. + +
      19. The link-time optimizer now runs the -prune-eh pass (to remove unused +exception handlers.
      20. +
      @@ -562,7 +586,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
      - Last modified: $Date: 2004/04/06 19:48:42 $ + Last modified: $Date: 2004/04/13 14:43:35 $ From lattner at cs.uiuc.edu Tue Apr 13 10:22:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 10:22:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopSimplify.cpp Message-ID: <200404131521.KAA13186@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopSimplify.cpp updated: 1.40 -> 1.41 --- Log message: Refactor code a bit to make it simpler and eliminate the goto --- Diffs of the changes: (+31 -27) Index: llvm/lib/Transforms/Scalar/LoopSimplify.cpp diff -u llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.40 llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.41 --- llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.40 Tue Apr 13 00:05:33 2004 +++ llvm/lib/Transforms/Scalar/LoopSimplify.cpp Tue Apr 13 10:21:18 2004 @@ -469,6 +469,28 @@ VerifyExitBlocks(*I); } +/// FindPHIToPartitionLoops - The first part of loop-nestification is to find a +/// PHI node that tells us how to partition the loops. +static PHINode *FindPHIToPartitionLoops(Loop *L) { + for (BasicBlock::iterator I = L->getHeader()->begin(); + PHINode *PN = dyn_cast(I); ) { + ++I; + if (Value *V = hasConstantValue(PN)) { + // This is a degenerate PHI already, don't modify it! + PN->replaceAllUsesWith(V); + PN->getParent()->getInstList().erase(PN); + } else { + // Scan this PHI node looking for a use of the PHI node by itself. + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) + if (PN->getIncomingValue(i) == PN && + L->contains(PN->getIncomingBlock(i))) + // We found something tasty to remove. + return PN; + } + } + return 0; +} + /// SeparateNestedLoop - If this loop has multiple backedges, try to pull one of /// them out into a nested loop. This is important for code that looks like /// this: @@ -488,36 +510,18 @@ /// Loop *LoopSimplify::SeparateNestedLoop(Loop *L) { BasicBlock *Header = L->getHeader(); + PHINode *PN = FindPHIToPartitionLoops(L); + if (PN == 0) return 0; // No known way to partition. + // Pull out all predecessors that have varying values in the loop. This + // handles the case when a PHI node has multiple instances of itself as + // arguments. std::vector OuterLoopPreds; - for (BasicBlock::iterator I = Header->begin(); - PHINode *PN = dyn_cast(I); ) { - ++I; - if (Value *V = hasConstantValue(PN)) { - // This is a degenerate PHI already, don't modify it! - PN->replaceAllUsesWith(V); - Header->getInstList().erase(PN); - continue; - } - - // Scan this PHI node looking for a use of the PHI node by itself. - for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) - if (PN->getIncomingValue(i) == PN && - L->contains(PN->getIncomingBlock(i))) { - // Wow, we found something tasty to remove. Pull out all predecessors - // that have varying values in the loop. This handles the case when a - // PHI node has multiple instances of itself as arguments. - for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) - if (PN->getIncomingValue(i) != PN || - !L->contains(PN->getIncomingBlock(i))) - OuterLoopPreds.push_back(PN->getIncomingBlock(i)); - goto FoundExtraction; - } - } - - return 0; // Nothing looks appetizing to separate out + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) + if (PN->getIncomingValue(i) != PN || + !L->contains(PN->getIncomingBlock(i))) + OuterLoopPreds.push_back(PN->getIncomingBlock(i)); -FoundExtraction: BasicBlock *NewBB = SplitBlockPredecessors(Header, ".outer", OuterLoopPreds); // Update dominator information (set, immdom, domtree, and domfrontier) From lattner at cs.uiuc.edu Tue Apr 13 11:23:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 11:23:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/LoopSimplify/2004-04-13-LoopSimplifyUpdateDomFrontier.ll Message-ID: <200404131622.LAA08175@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/LoopSimplify: 2004-04-13-LoopSimplifyUpdateDomFrontier.ll added (r1.1) --- Log message: New testcase where loop simplify is not updating domfrontiers correctly --- Diffs of the changes: (+22 -0) Index: llvm/test/Regression/Transforms/LoopSimplify/2004-04-13-LoopSimplifyUpdateDomFrontier.ll diff -c /dev/null llvm/test/Regression/Transforms/LoopSimplify/2004-04-13-LoopSimplifyUpdateDomFrontier.ll:1.1 *** /dev/null Tue Apr 13 11:22:14 2004 --- llvm/test/Regression/Transforms/LoopSimplify/2004-04-13-LoopSimplifyUpdateDomFrontier.ll Tue Apr 13 11:22:04 2004 *************** *** 0 **** --- 1,22 ---- + ; RUN: llvm-as < %s | opt -scalarrepl -loopsimplify -licm -disable-output + + implementation ; Functions: + + void %inflate() { + entry: + br label %loopentry.0.outer1111 + + loopentry.0.outer1111: ; preds = %entry, %loopentry.0.outer1111, %label.11, %then.41 + %left.0.ph1107 = phi uint [ %tmp.1172, %then.41 ], [ 0, %entry ], [ %tmp.1172, %label.11 ], [ %left.0.ph1107, %loopentry.0.outer1111 ] ; [#uses=2] + %tmp.1172 = sub uint %left.0.ph1107, 0 ; [#uses=2] + switch uint 0, label %label.11 [ + uint 23, label %loopentry.0.outer1111 + uint 13, label %then.41 + ] + + label.11: ; preds = %loopentry.0.outer1111 + br label %loopentry.0.outer1111 + + then.41: ; preds = %loopentry.0.outer1111 + br label %loopentry.0.outer1111 + } From lattner at cs.uiuc.edu Tue Apr 13 11:24:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 11:24:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopSimplify.cpp Message-ID: <200404131623.LAA24007@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopSimplify.cpp updated: 1.41 -> 1.42 --- Log message: Fix LoopSimplify/2004-04-13-LoopSimplifyUpdateDomFrontier.ll LoopSimplify was not updating dominator frontiers correctly in some cases. --- Diffs of the changes: (+42 -26) Index: llvm/lib/Transforms/Scalar/LoopSimplify.cpp diff -u llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.41 llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.42 --- llvm/lib/Transforms/Scalar/LoopSimplify.cpp:1.41 Tue Apr 13 10:21:18 2004 +++ llvm/lib/Transforms/Scalar/LoopSimplify.cpp Tue Apr 13 11:23:25 2004 @@ -509,7 +509,6 @@ /// created. /// Loop *LoopSimplify::SeparateNestedLoop(Loop *L) { - BasicBlock *Header = L->getHeader(); PHINode *PN = FindPHIToPartitionLoops(L); if (PN == 0) return 0; // No known way to partition. @@ -522,6 +521,7 @@ !L->contains(PN->getIncomingBlock(i))) OuterLoopPreds.push_back(PN->getIncomingBlock(i)); + BasicBlock *Header = L->getHeader(); BasicBlock *NewBB = SplitBlockPredecessors(Header, ".outer", OuterLoopPreds); // Update dominator information (set, immdom, domtree, and domfrontier) @@ -830,9 +830,9 @@ // Update dominance frontier information... if (DominanceFrontier *DF = getAnalysisToUpdate()) { - // If NewBB dominates NewBBSucc, then the global dominance frontiers are not - // changed. DF(NewBB) is now going to be the DF(PredBlocks[0]) without the - // stuff that the new block does not dominate a predecessor of. + // If NewBB dominates NewBBSucc, then DF(NewBB) is now going to be the + // DF(PredBlocks[0]) without the stuff that the new block does not dominate + // a predecessor of. if (NewBBDominatesNewBBSucc) { DominanceFrontier::iterator DFI = DF->find(PredBlocks[0]); if (DFI != DF->end()) { @@ -861,29 +861,45 @@ DominanceFrontier::DomSetType NewDFSet; NewDFSet.insert(NewBBSucc); DF->addBasicBlock(NewBB, NewDFSet); - - // Now we must loop over all of the dominance frontiers in the function, - // replacing occurrences of NewBBSucc with NewBB in some cases. All - // blocks that dominate a block in PredBlocks and contained NewBBSucc in - // their dominance frontier must be updated to contain NewBB instead. - // - for (unsigned i = 0, e = PredBlocks.size(); i != e; ++i) { - BasicBlock *Pred = PredBlocks[i]; - // Get all of the dominators of the predecessor... - const DominatorSet::DomSetType &PredDoms = DS.getDominators(Pred); - for (DominatorSet::DomSetType::const_iterator PDI = PredDoms.begin(), - PDE = PredDoms.end(); PDI != PDE; ++PDI) { - BasicBlock *PredDom = *PDI; - - // If the NewBBSucc node is in DF(PredDom), then PredDom didn't - // dominate NewBBSucc but did dominate a predecessor of it. Now we - // change this entry to include NewBB in the DF instead of NewBBSucc. - DominanceFrontier::iterator DFI = DF->find(PredDom); - assert(DFI != DF->end() && "No dominance frontier for node?"); - if (DFI->second.count(NewBBSucc)) { - DF->removeFromFrontier(DFI, NewBBSucc); - DF->addToFrontier(DFI, NewBB); + } + + // Now we must loop over all of the dominance frontiers in the function, + // replacing occurrences of NewBBSucc with NewBB in some cases. All + // blocks that dominate a block in PredBlocks and contained NewBBSucc in + // their dominance frontier must be updated to contain NewBB instead. + // + for (unsigned i = 0, e = PredBlocks.size(); i != e; ++i) { + BasicBlock *Pred = PredBlocks[i]; + // Get all of the dominators of the predecessor... + const DominatorSet::DomSetType &PredDoms = DS.getDominators(Pred); + for (DominatorSet::DomSetType::const_iterator PDI = PredDoms.begin(), + PDE = PredDoms.end(); PDI != PDE; ++PDI) { + BasicBlock *PredDom = *PDI; + + // If the NewBBSucc node is in DF(PredDom), then PredDom didn't + // dominate NewBBSucc but did dominate a predecessor of it. Now we + // change this entry to include NewBB in the DF instead of NewBBSucc. + DominanceFrontier::iterator DFI = DF->find(PredDom); + assert(DFI != DF->end() && "No dominance frontier for node?"); + if (DFI->second.count(NewBBSucc)) { + // If NewBBSucc should not stay in our dominator frontier, remove it. + // We remove it unless there is a predecessor of NewBBSucc that we + // dominate, but we don't strictly dominate NewBBSucc. + bool ShouldRemove = true; + if (PredDom == NewBBSucc || !DS.dominates(PredDom, NewBBSucc)) { + // Okay, we know that PredDom does not strictly dominate NewBBSucc. + // Check to see if it dominates any predecessors of NewBBSucc. + for (pred_iterator PI = pred_begin(NewBBSucc), + E = pred_end(NewBBSucc); PI != E; ++PI) + if (DS.dominates(PredDom, *PI)) { + ShouldRemove = false; + break; + } } + + if (ShouldRemove) + DF->removeFromFrontier(DFI, NewBBSucc); + DF->addToFrontier(DFI, NewBB); } } } From lattner at cs.uiuc.edu Tue Apr 13 11:25:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 11:25:01 2004 Subject: [llvm-commits] CVS: llvm/runtime/Makefile Message-ID: <200404131625.LAA26095@zion.cs.uiuc.edu> Changes in directory llvm/runtime: Makefile updated: 1.15 -> 1.16 --- Log message: Reenable library now that the loopsimplify bug is fixed --- Diffs of the changes: (+1 -1) Index: llvm/runtime/Makefile diff -u llvm/runtime/Makefile:1.15 llvm/runtime/Makefile:1.16 --- llvm/runtime/Makefile:1.15 Tue Apr 13 08:57:29 2004 +++ llvm/runtime/Makefile Tue Apr 13 11:24:53 2004 @@ -12,7 +12,7 @@ include $(LEVEL)/Makefile.config ifneq ($(wildcard $(LLVMGCCDIR)),) -PARALLEL_DIRS := GCCLibraries libdummy libprofile libtrace libpng +PARALLEL_DIRS := GCCLibraries libdummy libprofile libtrace libpng zlib else PARALLEL_DIRS := install all :: From lattner at cs.uiuc.edu Tue Apr 13 12:18:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 12:18:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/ioport.llx Message-ID: <200404131718.MAA08536@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: ioport.llx updated: 1.1 -> 1.2 --- Log message: Make the testcase more challenging --- Diffs of the changes: (+8 -5) Index: llvm/test/Regression/CodeGen/X86/ioport.llx diff -u llvm/test/Regression/CodeGen/X86/ioport.llx:1.1 llvm/test/Regression/CodeGen/X86/ioport.llx:1.2 --- llvm/test/Regression/CodeGen/X86/ioport.llx:1.1 Mon Apr 12 11:42:43 2004 +++ llvm/test/Regression/CodeGen/X86/ioport.llx Tue Apr 13 12:18:07 2004 @@ -5,14 +5,17 @@ declare int %llvm.readport (ushort) declare void %llvm.writeport (int, ushort) -uint %in (uint %p) { - %i1 = call int(ushort)* %llvm.readport (ushort 255) - ret uint 5 +int %in(ushort %p) { + %i1 = call int %llvm.readport (ushort 255) + %i2 = call int %llvm.readport (ushort %p) + %r = add int %i1, %i2 + ret int %r } -uint %out (uint %p) { +void %out(ushort %p) { call void(int, ushort)* %llvm.writeport (int 1, ushort 255) - ret uint 5 + call void(int, ushort)* %llvm.writeport (int 4, ushort %p) + ret void } From lattner at cs.uiuc.edu Tue Apr 13 12:19:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 12:19:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86CodeEmitter.cpp Message-ID: <200404131719.MAA08555@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86CodeEmitter.cpp updated: 1.57 -> 1.58 --- Log message: Add support for new instruction type --- Diffs of the changes: (+2 -0) Index: llvm/lib/Target/X86/X86CodeEmitter.cpp diff -u llvm/lib/Target/X86/X86CodeEmitter.cpp:1.57 llvm/lib/Target/X86/X86CodeEmitter.cpp:1.58 --- llvm/lib/Target/X86/X86CodeEmitter.cpp:1.57 Mon Mar 8 21:34:53 2004 +++ llvm/lib/Target/X86/X86CodeEmitter.cpp Tue Apr 13 12:18:51 2004 @@ -537,6 +537,8 @@ unsigned Address = MCE.getGlobalValueAddress(MO.getSymbolName()); assert(Address && "Unknown external symbol!"); emitMaybePCRelativeValue(Address, MO.isPCRelative()); + } else if (MO.isImmediate()) { + emitConstant(MO.getImmedValue(), sizeOfImm(Desc)); } else { assert(0 && "Unknown RawFrm operand!"); } From lattner at cs.uiuc.edu Tue Apr 13 12:21:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 12:21:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200404131720.MAA08616@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.75 -> 1.76 --- Log message: Add immediate forms of in/out. Use let to shorten lines --- Diffs of the changes: (+20 -8) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.75 llvm/lib/Target/X86/X86InstrInfo.td:1.76 --- llvm/lib/Target/X86/X86InstrInfo.td:1.75 Sun Apr 11 22:02:48 2004 +++ llvm/lib/Target/X86/X86InstrInfo.td Tue Apr 13 12:19:31 2004 @@ -151,7 +151,6 @@ // Helper for shift instructions class UsesCL { list Uses = [CL]; bit printImplicitUsesAfter = 1; } -class PrintImpUsesAfter {bit printImplicitUsesAfter = 1;} class PrintImpDefsAfter {bit printImplicitDefsAfter = 1;} //===----------------------------------------------------------------------===// @@ -248,13 +247,26 @@ //===----------------------------------------------------------------------===// // Input/Output Instructions... // -def IN8 : I<"in", 0xEC, RawFrm>, Imp<[DX],[AL]>, PrintImpUsesAfter, PrintImpDefsAfter; // in AL = I/O address DX -def IN16 : I<"in", 0xED, RawFrm>, Imp<[DX],[AX]>, OpSize, PrintImpUsesAfter, PrintImpDefsAfter; // in AX = I/O address DX -def IN32 : I<"in", 0xED, RawFrm>, Imp<[DX],[EAX]>, PrintImpUsesAfter, PrintImpDefsAfter; // in EAX = I/O address DX - -def OUT8 : I<"out", 0xEE, RawFrm>, Imp<[DX, AL], []>, PrintImpUsesAfter; -def OUT16 : I<"out", 0xEF, RawFrm>, Imp<[DX, AX], []>, OpSize, PrintImpUsesAfter; -def OUT32 : I<"out", 0xEF, RawFrm>, Imp<[DX, EAX], []>, PrintImpUsesAfter; +let printImplicitUsesAfter = 1, printImplicitDefsAfter = 1 in { + def IN8rr : I<"in", 0xEC, RawFrm>, Imp<[DX], [AL]>; // AL = in I/O address DX + def IN16rr : I<"in", 0xED, RawFrm>, Imp<[DX], [AX]>, OpSize; // AX = in I/O address DX + def IN32rr : I<"in", 0xED, RawFrm>, Imp<[DX],[EAX]>; // EAX = in I/O address DX +} + +let printImplicitDefsBefore = 1 in { + def IN8ri : Ii16<"in", 0xE4, RawFrm>, Imp<[], [AL]>; // AL = in [I/O address] + def IN16ri : Ii16<"in", 0xE5, RawFrm>, Imp<[], [AX]>, OpSize; // AX = in [I/O address] + def IN32ri : Ii16<"in", 0xE5, RawFrm>, Imp<[],[EAX]>; // EAX = in [I/O address] +} + +let printImplicitUsesAfter = 1 in { + def OUT8rr : I<"out", 0xEE, RawFrm>, Imp<[DX, AL], []>; + def OUT16rr : I<"out", 0xEF, RawFrm>, Imp<[DX, AX], []>, OpSize; + def OUT32rr : I<"out", 0xEF, RawFrm>, Imp<[DX, EAX], []>; + def OUT8ir : Ii16<"out", 0xE6, RawFrm>, Imp<[AL], []>; + def OUT16ir : Ii16<"out", 0xE7, RawFrm>, Imp<[AX], []>, OpSize; + def OUT32ir : Ii16<"out", 0xE7, RawFrm>, Imp<[EAX], []>; +} //===----------------------------------------------------------------------===// // Move Instructions... From lattner at cs.uiuc.edu Tue Apr 13 12:21:07 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 12:21:07 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200404131720.MAA08623@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.234 -> 1.235 --- Log message: Emit the immediate form of in/out when possible. Fix several bugs in the intrinsics: 1. Make sure to copy the input registers before the instructions that use them 2. Make sure to copy the value returned by 'in' out of EAX into the register it is supposed to be in. This fixes assertions when using in/out and linear scan. --- Diffs of the changes: (+82 -49) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.234 llvm/lib/Target/X86/InstSelectSimple.cpp:1.235 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.234 Sun Apr 11 22:02:48 2004 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Tue Apr 13 12:20:37 2004 @@ -1691,72 +1691,105 @@ return; } - case Intrinsic::readport: + case Intrinsic::readport: { + // First, determine that the size of the operand falls within the acceptable + // range for this architecture. // - // First, determine that the size of the operand falls within the - // acceptable range for this architecture. - // - if ((CI.getOperand(1)->getType()->getPrimitiveSize()) != 2) { + if (getClassB(CI.getOperand(1)->getType()) != cShort) { std::cerr << "llvm.readport: Address size is not 16 bits\n"; - exit (1); + exit(1); } - // // Now, move the I/O port address into the DX register and use the IN // instruction to get the input data. // - BuildMI(BB, X86::MOV16rr, 1, X86::DX).addReg(getReg(CI.getOperand(1))); - switch (CI.getCalledFunction()->getReturnType()->getPrimitiveSize()) { - case 1: - BuildMI(BB, X86::IN8, 0); - break; - case 2: - BuildMI(BB, X86::IN16, 0); - break; - case 4: - BuildMI(BB, X86::IN32, 0); - break; - default: - std::cerr << "Cannot do input on this data type"; - exit (1); + unsigned Class = getClass(CI.getCalledFunction()->getReturnType()); + unsigned DestReg = getReg(CI); + + // If the port is a single-byte constant, use the immediate form. + if (ConstantInt *C = dyn_cast(CI.getOperand(1))) + if ((C->getRawValue() & 255) == C->getRawValue()) { + switch (Class) { + case cByte: + BuildMI(BB, X86::IN8ri, 1).addImm((unsigned char)C->getRawValue()); + BuildMI(BB, X86::MOV8rr, 1, DestReg).addReg(X86::AL); + return; + case cShort: + BuildMI(BB, X86::IN16ri, 1).addImm((unsigned char)C->getRawValue()); + BuildMI(BB, X86::MOV8rr, 1, DestReg).addReg(X86::AX); + return; + case cInt: + BuildMI(BB, X86::IN32ri, 1).addImm((unsigned char)C->getRawValue()); + BuildMI(BB, X86::MOV8rr, 1, DestReg).addReg(X86::EAX); + return; + } + } + + unsigned Reg = getReg(CI.getOperand(1)); + BuildMI(BB, X86::MOV16rr, 1, X86::DX).addReg(Reg); + switch (Class) { + case cByte: + BuildMI(BB, X86::IN8rr, 0); + BuildMI(BB, X86::MOV8rr, 1, DestReg).addReg(X86::AL); + break; + case cShort: + BuildMI(BB, X86::IN16rr, 0); + BuildMI(BB, X86::MOV8rr, 1, DestReg).addReg(X86::AX); + break; + case cInt: + BuildMI(BB, X86::IN32rr, 0); + BuildMI(BB, X86::MOV8rr, 1, DestReg).addReg(X86::EAX); + break; + default: + std::cerr << "Cannot do input on this data type"; + exit (1); } return; + } - case Intrinsic::writeport: - // + case Intrinsic::writeport: { // First, determine that the size of the operand falls within the // acceptable range for this architecture. - // - // - if ((CI.getOperand(2)->getType()->getPrimitiveSize()) != 2) { + if (getClass(CI.getOperand(2)->getType()) != cShort) { std::cerr << "llvm.writeport: Address size is not 16 bits\n"; - exit (1); + exit(1); } - // - // Now, move the I/O port address into the DX register and the value to - // write into the AL/AX/EAX register. - // - BuildMI(BB, X86::MOV16rr, 1, X86::DX).addReg(getReg(CI.getOperand(2))); - switch (CI.getOperand(1)->getType()->getPrimitiveSize()) { - case 1: - BuildMI(BB, X86::MOV8rr, 1, X86::AL).addReg(getReg(CI.getOperand(1))); - BuildMI(BB, X86::OUT8, 0); - break; - case 2: - BuildMI(BB, X86::MOV16rr, 1, X86::AX).addReg(getReg(CI.getOperand(1))); - BuildMI(BB, X86::OUT16, 0); - break; - case 4: - BuildMI(BB, X86::MOV32rr, 1, X86::EAX).addReg(getReg(CI.getOperand(1))); - BuildMI(BB, X86::OUT32, 0); - break; - default: - std::cerr << "Cannot do output on this data type"; - exit (1); + unsigned Class = getClassB(CI.getOperand(1)->getType()); + unsigned ValReg = getReg(CI.getOperand(1)); + switch (Class) { + case cByte: + BuildMI(BB, X86::MOV8rr, 1, X86::AL).addReg(ValReg); + break; + case cShort: + BuildMI(BB, X86::MOV16rr, 1, X86::AX).addReg(ValReg); + break; + case cInt: + BuildMI(BB, X86::MOV32rr, 1, X86::EAX).addReg(ValReg); + break; + default: + std::cerr << "llvm.writeport: invalid data type for X86 target"; + exit(1); } - return; + + // If the port is a single-byte constant, use the immediate form. + if (ConstantInt *C = dyn_cast(CI.getOperand(2))) + if ((C->getRawValue() & 255) == C->getRawValue()) { + static const unsigned O[] = { X86::OUT8ir, X86::OUT16ir, X86::OUT32ir }; + BuildMI(BB, O[Class], 1).addImm((unsigned char)C->getRawValue()); + return; + } + + // Otherwise, move the I/O port address into the DX register and the value + // to write into the AL/AX/EAX register. + static const unsigned Opc[] = { X86::OUT8rr, X86::OUT16rr, X86::OUT32rr }; + unsigned Reg = getReg(CI.getOperand(2)); + BuildMI(BB, X86::MOV16rr, 1, X86::DX).addReg(Reg); + BuildMI(BB, Opc[Class], 0); + return; + } + default: assert(0 && "Error: unknown intrinsics should have been lowered!"); } } From lattner at cs.uiuc.edu Tue Apr 13 12:21:12 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 12:21:12 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/Printer.cpp X86.td X86InstrInfo.h Message-ID: <200404131720.MAA08632@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: Printer.cpp updated: 1.96 -> 1.97 X86.td updated: 1.10 -> 1.11 X86InstrInfo.h updated: 1.38 -> 1.39 --- Log message: Add support for the printImplicitDefsBefore flag --- Diffs of the changes: (+38 -7) Index: llvm/lib/Target/X86/Printer.cpp diff -u llvm/lib/Target/X86/Printer.cpp:1.96 llvm/lib/Target/X86/Printer.cpp:1.97 --- llvm/lib/Target/X86/Printer.cpp:1.96 Thu Apr 8 15:31:46 2004 +++ llvm/lib/Target/X86/Printer.cpp Tue Apr 13 12:18:39 2004 @@ -105,6 +105,7 @@ } void printImplUsesBefore(const TargetInstrDescriptor &Desc); + bool printImplDefsBefore(const TargetInstrDescriptor &Desc); bool printImplUsesAfter(const TargetInstrDescriptor &Desc, const bool LC); bool printImplDefsAfter(const TargetInstrDescriptor &Desc, const bool LC); void printMachineInstruction(const MachineInstr *MI); @@ -544,6 +545,30 @@ } } +/// printImplDefsBefore - Emit the implicit-def registers for the instruction +/// described by DESC, if its PrintImplUsesBefore flag is set. Return true if +/// we printed any registers. +/// +bool Printer::printImplDefsBefore(const TargetInstrDescriptor &Desc) { + bool Printed = false; + const MRegisterInfo &RI = *TM.getRegisterInfo(); + if (Desc.TSFlags & X86II::PrintImplDefsBefore) { + const unsigned *p = Desc.ImplicitDefs; + if (*p) { + O << (Printed ? ", %" : "%") << RI.get (*p).Name; + Printed = true; + ++p; + } + while (*p) { + // Bug Workaround: See note in Printer::doInitialization about %. + O << ", %" << RI.get(*p).Name; + ++p; + } + } + return Printed; +} + + /// printImplUsesAfter - Emit the implicit-use registers for the instruction /// described by DESC, if its PrintImplUsesAfter flag is set. /// @@ -655,22 +680,25 @@ case X86II::RawFrm: { - bool LeadingComma = false; - // The accepted forms of Raw instructions are: // 1. nop - No operand required // 2. jmp foo - PC relative displacement operand // 3. call bar - GlobalAddress Operand or External Symbol Operand + // 4. in AL, imm - Immediate operand // assert(MI->getNumOperands() == 0 || (MI->getNumOperands() == 1 && (MI->getOperand(0).isPCRelativeDisp() || MI->getOperand(0).isGlobalAddress() || - MI->getOperand(0).isExternalSymbol())) && + MI->getOperand(0).isExternalSymbol() || + MI->getOperand(0).isImmediate())) && "Illegal raw instruction!"); O << TII.getName(MI->getOpcode()) << " "; + bool LeadingComma = printImplDefsBefore(Desc); + if (MI->getNumOperands() == 1) { + if (LeadingComma) O << ", "; printOp(MI->getOperand(0), true); // Don't print "OFFSET"... LeadingComma = true; } Index: llvm/lib/Target/X86/X86.td diff -u llvm/lib/Target/X86/X86.td:1.10 llvm/lib/Target/X86/X86.td:1.11 --- llvm/lib/Target/X86/X86.td:1.10 Thu Apr 8 15:31:47 2004 +++ llvm/lib/Target/X86/X86.td Tue Apr 13 12:18:39 2004 @@ -41,6 +41,7 @@ "FPFormBits", "printImplicitUsesAfter", "printImplicitUsesBefore", + "printImplicitDefsBefore", "printImplicitDefsAfter", "Opcode"]; let TSFlagsShifts = [0, @@ -52,7 +53,8 @@ 18, 19, 20, - 21]; + 21, + 22]; } def X86 : Target { Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.38 llvm/lib/Target/X86/X86InstrInfo.h:1.39 --- llvm/lib/Target/X86/X86InstrInfo.h:1.38 Thu Apr 8 15:31:47 2004 +++ llvm/lib/Target/X86/X86InstrInfo.h Tue Apr 13 12:18:39 2004 @@ -171,11 +171,12 @@ // PrintImplDefsAfter - Print out implicit defs in the assembly output // after the normal operands. - PrintImplDefsAfter = 1 << 20, + PrintImplDefsBefore = 1 << 20, + PrintImplDefsAfter = 1 << 21, - OpcodeShift = 21, + OpcodeShift = 22, OpcodeMask = 0xFF << OpcodeShift, - // Bits 26 -> 31 are unused + // Bits 27 -> 31 are unused }; } From gaeke at cs.uiuc.edu Tue Apr 13 13:24:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Apr 13 13:24:01 2004 Subject: [llvm-commits] CVS: llvm/utils/Spiff/output.c Message-ID: <200404131824.NAA11739@zion.cs.uiuc.edu> Changes in directory llvm/utils/Spiff: output.c updated: 1.2 -> 1.3 --- Log message: Don't underline diffs --- Diffs of the changes: (+3 -2) Index: llvm/utils/Spiff/output.c diff -u llvm/utils/Spiff/output.c:1.2 llvm/utils/Spiff/output.c:1.3 --- llvm/utils/Spiff/output.c:1.2 Mon Apr 12 22:24:45 2004 +++ llvm/utils/Spiff/output.c Tue Apr 13 13:24:01 2004 @@ -8,7 +8,7 @@ #ifndef lint -static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/output.c,v 1.2 2004/04/13 03:24:45 gaeke Exp $"; +static char rcsid[]= "$Header: /home/vadve/shared/PublicCVS/llvm/utils/Spiff/output.c,v 1.3 2004/04/13 18:24:01 gaeke Exp $"; #endif #include @@ -124,7 +124,8 @@ } else { - _O_doing_ul = 1; + /* _O_doing_ul = 1; */ /* disabled by brg 13-April-2004 - this + makes the output unreadable */ } } From lattner at cs.uiuc.edu Tue Apr 13 13:29:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 13:29:01 2004 Subject: [llvm-commits] CVS: llvm/test/Programs/DiffOutput.sh Makefile.programs Message-ID: <200404131828.NAA08720@apoc.cs.uiuc.edu> Changes in directory llvm/test/Programs: DiffOutput.sh updated: 1.15 -> 1.16 Makefile.programs updated: 1.125 -> 1.126 --- Log message: Use spiff to perform our diffs. This is nice for two reasons: 1. We can eliminate the nasty code looking for gdiff/diff 2. We can specify a tolerance that our FP numbers are allowed to differ by, eliminating spurious failures in the testsuite. :) :) --- Diffs of the changes: (+12 -17) Index: llvm/test/Programs/DiffOutput.sh diff -u llvm/test/Programs/DiffOutput.sh:1.15 llvm/test/Programs/DiffOutput.sh:1.16 --- llvm/test/Programs/DiffOutput.sh:1.15 Sun Jan 11 23:24:26 2004 +++ llvm/test/Programs/DiffOutput.sh Tue Apr 13 13:28:12 2004 @@ -4,7 +4,7 @@ # DiffOutput.sh # # SYNOPSIS -# DiffOutput.sh [] +# DiffOutput.sh [] # # DESCRIPTION # DiffOutput.sh looks for a file named Output/.out- @@ -21,28 +21,18 @@ # # Command line parameters: -WHICHOUTPUT=$1 -PROG=$2 -GOODOUTPUT=${3-nat} +DIFF=$1 +WHICHOUTPUT=$2 +PROG=$3 +GOODOUTPUT=${4-nat} # Output filename: DIFFOUTPUT=Output/${PROG}.diff-${WHICHOUTPUT} # Input filenames: TESTOUTPUT=Output/${PROG}.out-${WHICHOUTPUT} GOODOUTPUT=Output/${PROG}.out-${GOODOUTPUT} -# Find gnu diff -DIFF=diff -if which gdiff > /dev/null 2>&1 -then - where=`which gdiff 2>&1` - if [ -x "$where" ] - then - DIFF=gdiff - fi -fi - # Diff the two files. -$DIFF -u $GOODOUTPUT $TESTOUTPUT > $DIFFOUTPUT || ( +$DIFF $GOODOUTPUT $TESTOUTPUT > $DIFFOUTPUT || ( # They are different! echo "******************** TEST ($WHICHOUTPUT) '$PROG' FAILED! ********************" echo "Execution Context Diff:" Index: llvm/test/Programs/Makefile.programs diff -u llvm/test/Programs/Makefile.programs:1.125 llvm/test/Programs/Makefile.programs:1.126 --- llvm/test/Programs/Makefile.programs:1.125 Sat Apr 10 11:53:06 2004 +++ llvm/test/Programs/Makefile.programs Tue Apr 13 13:28:12 2004 @@ -55,8 +55,13 @@ # TIMEPROG - The program used to get timing results for a program TIMEPROG := $(PROGDIR)/TimeProgram.sh +TOLERANCEOPT := +ifdef FP_TOLERANCE +TOLERANCEOPT := -r$(FP_TOLERANCE) +endif + # DIFFPROG - The program used to diff the output -DIFFPROG := $(PROGDIR)/DiffOutput.sh +DIFFPROG := $(PROGDIR)/DiffOutput.sh "$(LLVMTOOLCURRENT)/spiff $(TOLERANCEOPT)" # RUNTIMELIMIT - The number of seconds we should wait before certain events # timeout. This is overridable on the commandline or in tests makefiles. From lattner at cs.uiuc.edu Tue Apr 13 13:30:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 13:30:02 2004 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/Benchmarks/Olden/health/Makefile Message-ID: <200404131829.NAA20088@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Benchmarks/Olden/health: Makefile updated: 1.13 -> 1.14 --- Log message: Specify a tolerance --- Diffs of the changes: (+3 -0) Index: llvm/test/Programs/MultiSource/Benchmarks/Olden/health/Makefile diff -u llvm/test/Programs/MultiSource/Benchmarks/Olden/health/Makefile:1.13 llvm/test/Programs/MultiSource/Benchmarks/Olden/health/Makefile:1.14 --- llvm/test/Programs/MultiSource/Benchmarks/Olden/health/Makefile:1.13 Fri Sep 12 11:02:26 2003 +++ llvm/test/Programs/MultiSource/Benchmarks/Olden/health/Makefile Tue Apr 13 13:29:19 2004 @@ -3,6 +3,9 @@ PROG = health CPPFLAGS = -DTORONTO LDFLAGS = -lm + +FP_TOLERANCE = 0.001 + ifdef LARGE_PROBLEM_SIZE RUN_OPTIONS = 10 40 1 else From lattner at cs.uiuc.edu Tue Apr 13 13:34:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 13:34:01 2004 Subject: [llvm-commits] CVS: llvm/utils/Spiff/Makefile Message-ID: <200404131833.NAA02019@zion.cs.uiuc.edu> Changes in directory llvm/utils/Spiff: Makefile updated: 1.1 -> 1.2 --- Log message: Really spiff, don't chatter :) --- Diffs of the changes: (+1 -1) Index: llvm/utils/Spiff/Makefile diff -u llvm/utils/Spiff/Makefile:1.1 llvm/utils/Spiff/Makefile:1.2 --- llvm/utils/Spiff/Makefile:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/Makefile Tue Apr 13 13:33:21 2004 @@ -1,6 +1,6 @@ LEVEL = ../.. TOOLNAME = spiff +CPPFLAGS += -DATT -DNOCHATTER include $(LEVEL)/Makefile.common -CPPFLAGS += -DATT -DNOCHATTER From lattner at cs.uiuc.edu Tue Apr 13 13:35:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 13:35:02 2004 Subject: [llvm-commits] CVS: llvm/utils/Spiff/line.h Message-ID: <200404131834.NAA02266@zion.cs.uiuc.edu> Changes in directory llvm/utils/Spiff: line.h updated: 1.1 -> 1.2 --- Log message: Fixed sized limits are bad... duh. --- Diffs of the changes: (+1 -1) Index: llvm/utils/Spiff/line.h diff -u llvm/utils/Spiff/line.h:1.1 llvm/utils/Spiff/line.h:1.2 --- llvm/utils/Spiff/line.h:1.1 Mon Apr 12 17:53:24 2004 +++ llvm/utils/Spiff/line.h Tue Apr 13 13:34:16 2004 @@ -9,7 +9,7 @@ #ifndef L_INCLUDED -#define _L_MAXLINES 10000 +#define _L_MAXLINES 100000 /* ** oh god, is this an ugly implementation. From lattner at cs.uiuc.edu Tue Apr 13 13:36:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 13:36:02 2004 Subject: [llvm-commits] CVS: llvm/test/Programs/MultiSource/Benchmarks/Olden/voronoi/Makefile Message-ID: <200404131835.NAA04286@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/MultiSource/Benchmarks/Olden/voronoi: Makefile updated: 1.13 -> 1.14 --- Log message: Make voronoi pass --- Diffs of the changes: (+1 -0) Index: llvm/test/Programs/MultiSource/Benchmarks/Olden/voronoi/Makefile diff -u llvm/test/Programs/MultiSource/Benchmarks/Olden/voronoi/Makefile:1.13 llvm/test/Programs/MultiSource/Benchmarks/Olden/voronoi/Makefile:1.14 --- llvm/test/Programs/MultiSource/Benchmarks/Olden/voronoi/Makefile:1.13 Sun Nov 16 13:40:59 2003 +++ llvm/test/Programs/MultiSource/Benchmarks/Olden/voronoi/Makefile Tue Apr 13 13:35:20 2004 @@ -4,6 +4,7 @@ INCLUDES = defines.h CPPFLAGS = -DTORONTO LDFLAGS = -lm +FP_TOLERANCE = 0.0001 ifdef LARGE_PROBLEM_SIZE RUN_OPTIONS = 1000000 20 32 7 endif From lattner at cs.uiuc.edu Tue Apr 13 13:38:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 13:38:01 2004 Subject: [llvm-commits] CVS: llvm/utils/getsrcs.sh Message-ID: <200404131838.NAA04566@zion.cs.uiuc.edu> Changes in directory llvm/utils: getsrcs.sh updated: 1.14 -> 1.15 --- Log message: Don't index spiff. It should not count as lines of LLVM code --- Diffs of the changes: (+1 -1) Index: llvm/utils/getsrcs.sh diff -u llvm/utils/getsrcs.sh:1.14 llvm/utils/getsrcs.sh:1.15 --- llvm/utils/getsrcs.sh:1.14 Sun Feb 29 20:41:22 2004 +++ llvm/utils/getsrcs.sh Tue Apr 13 13:37:51 2004 @@ -5,6 +5,6 @@ grep -v llvmAsmParser.cpp | grep -v llvmAsmParser.h | grep -v '~$' | \ grep -v '\.ll$' | grep -v .flc | grep -v Sparc.burm.c | grep -v '\.d$' |\ grep -v '\.dir$' | grep -v www/docs/doxygen | grep -v include/boost | \ - grep -v /Burg/ | grep -v '\.lo' | grep -v '\.inc$' | grep -v '\.libs' | \ + grep -v /Burg/ | grep -v /Spiff/ | grep -v '\.lo' | grep -v '\.inc$' | grep -v '\.libs' | \ grep -v TableGen/FileParser.cpp | grep -v TableGen/FileParser.h From lattner at cs.uiuc.edu Tue Apr 13 13:45:09 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 13:45:09 2004 Subject: [llvm-commits] CVS: llvm/utils/Spiff/line.h Message-ID: <200404131843.NAA06071@zion.cs.uiuc.edu> Changes in directory llvm/utils/Spiff: line.h updated: 1.2 -> 1.3 --- Log message: Increase buffer size again. *sigh* --- Diffs of the changes: (+1 -1) Index: llvm/utils/Spiff/line.h diff -u llvm/utils/Spiff/line.h:1.2 llvm/utils/Spiff/line.h:1.3 --- llvm/utils/Spiff/line.h:1.2 Tue Apr 13 13:34:16 2004 +++ llvm/utils/Spiff/line.h Tue Apr 13 13:43:18 2004 @@ -9,7 +9,7 @@ #ifndef L_INCLUDED -#define _L_MAXLINES 100000 +#define _L_MAXLINES 300000 /* ** oh god, is this an ugly implementation. From gaeke at cs.uiuc.edu Tue Apr 13 14:03:02 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Apr 13 14:03:02 2004 Subject: [llvm-commits] CVS: llvm/autoconf/configure.ac Message-ID: <200404131903.OAA21874@zion.cs.uiuc.edu> Changes in directory llvm/autoconf: configure.ac updated: 1.83 -> 1.84 --- Log message: Rewrite POV-Ray check as per PR301: http://llvm.cs.uiuc.edu/PR301 --- Diffs of the changes: (+35 -20) Index: llvm/autoconf/configure.ac diff -u llvm/autoconf/configure.ac:1.83 llvm/autoconf/configure.ac:1.84 --- llvm/autoconf/configure.ac:1.83 Fri Apr 2 15:06:44 2004 +++ llvm/autoconf/configure.ac Tue Apr 13 14:02:51 2004 @@ -342,28 +342,43 @@ AC_SUBST(USE_SPEC95,[[USE_SPEC95=1]]) fi -dnl Povray External Benchmark -AC_ARG_ENABLE(povray,AC_HELP_STRING([--enable-povray],[Compile Povray benchmark (default is NO)]),,enableval=no) -if test ${enableval} = "no" -then - if test -d /home/vadve/shared/benchmarks/povray31 +dnl We can use POV-Ray as an external benchmark, if they have the sources. +AC_ARG_ENABLE(povray, + AC_HELP_STRING([--enable-povray=ARG], + [Use POV-Ray as a benchmark (srcs in DIR)]), + povray=$enableval, + povray=auto) +AC_MSG_CHECKING([for POV-Ray benchmark sources]) +case "$povray" in +yes) + defaultdir=/home/vadve/shared/benchmarks/povray31 + if test -d $defaultdir then - AC_SUBST(POVRAY_ROOT,[/home/vadve/shared/benchmarks/povray31]) + AC_SUBST(POVRAY_ROOT,[$defaultdir]) AC_SUBST(USE_POVRAY,[[USE_POVRAY=1]]) - else - AC_SUBST(USE_POVRAY,[[]]) - AC_SUBST(POVRAY_ROOT,[]) - fi -else - if test ${enableval} = "" - then - AC_SUBST(POVRAY_ROOT,[/home/vadve/shared/benchmarks/povray31]) - else - AC_SUBST(POVRAY_ROOT,[${enableval}]) - fi - AC_SUBST(USE_POVRAY,[[USE_POVRAY=1]]) -fi - + povray="yes, found in $defaultdir" + else + povray=no + fi + ;; +auto|no) + AC_SUBST(POVRAY_ROOT,[]) + AC_SUBST(USE_POVRAY,[[]]) + povray=no + ;; +*) if test -d "$povray" + then + AC_SUBST(POVRAY_ROOT,"$povray") + AC_SUBST(USE_POVRAY,[[USE_POVRAY=1]]) + povray="yes, in $povray" + else + AC_SUBST(POVRAY_ROOT,[]) + AC_SUBST(USE_POVRAY,[[]]) + povray="no, not found in $povray" + fi + ;; +esac +AC_MSG_RESULT($povray) dnl Precompiled Bytecode Option AC_ARG_ENABLE(precompiled_bytecode,AC_HELP_STRING([--enable-precompiled_bytecode],[Use pre-compiled bytecode (default is NO)]),,enableval=no) From gaeke at cs.uiuc.edu Tue Apr 13 14:04:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Apr 13 14:04:01 2004 Subject: [llvm-commits] CVS: llvm/configure Message-ID: <200404131904.OAA22119@zion.cs.uiuc.edu> Changes in directory llvm: configure updated: 1.85 -> 1.86 --- Log message: Regenerated using autoconf-2.57. --- Diffs of the changes: (+32 -19) Index: llvm/configure diff -u llvm/configure:1.85 llvm/configure:1.86 --- llvm/configure:1.85 Fri Apr 2 15:26:02 2004 +++ llvm/configure Tue Apr 13 14:03:49 2004 @@ -1033,7 +1033,7 @@ --enable-optimized Compile with optimizations enabled (default is NO) --enable-spec2000 Compile SPEC 2000 benchmarks (default is NO) --enable-spec95 Compile SPEC 95 benchmarks (default is NO) - --enable-povray Compile Povray benchmark (default is NO) + --enable-povray=ARG Use POV-Ray as a benchmark (srcs in DIR) --enable-precompiled_bytecode Use pre-compiled bytecode (default is NO) --enable-llc_diffs Enable LLC Diffs when testing (default is YES) @@ -21900,36 +21900,49 @@ # Check whether --enable-povray or --disable-povray was given. if test "${enable_povray+set}" = set; then enableval="$enable_povray" - + povray=$enableval else - enableval=no + povray=auto fi; -if test ${enableval} = "no" -then - if test -d /home/vadve/shared/benchmarks/povray31 +echo "$as_me:$LINENO: checking for POV-Ray benchmark sources" >&5 +echo $ECHO_N "checking for POV-Ray benchmark sources... $ECHO_C" >&6 +case "$povray" in +yes) + defaultdir=/home/vadve/shared/benchmarks/povray31 + if test -d $defaultdir then - POVRAY_ROOT=/home/vadve/shared/benchmarks/povray31 + POVRAY_ROOT=$defaultdir USE_POVRAY=USE_POVRAY=1 - else - USE_POVRAY= + povray="yes, found in $defaultdir" + else + povray=no + fi + ;; +auto|no) + USE_POVRAY= - fi -else - if test ${enableval} = "" - then - POVRAY_ROOT=/home/vadve/shared/benchmarks/povray31 + povray=no + ;; +*) if test -d "$povray" + then + POVRAY_ROOT="$povray" - else - POVRAY_ROOT=${enableval} + USE_POVRAY=USE_POVRAY=1 - fi - USE_POVRAY=USE_POVRAY=1 + povray="yes, in $povray" + else -fi + USE_POVRAY= + povray="no, not found in $povray" + fi + ;; +esac +echo "$as_me:$LINENO: result: $povray" >&5 +echo "${ECHO_T}$povray" >&6 # Check whether --enable-precompiled_bytecode or --disable-precompiled_bytecode was given. if test "${enable_precompiled_bytecode+set}" = set; then From lattner at cs.uiuc.edu Tue Apr 13 14:28:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 14:28:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/ConstProp/calls.ll Message-ID: <200404131928.OAA00901@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/ConstProp: calls.ll added (r1.1) --- Log message: New testcase --- Diffs of the changes: (+17 -0) Index: llvm/test/Regression/Transforms/ConstProp/calls.ll diff -c /dev/null llvm/test/Regression/Transforms/ConstProp/calls.ll:1.1 *** /dev/null Tue Apr 13 14:28:19 2004 --- llvm/test/Regression/Transforms/ConstProp/calls.ll Tue Apr 13 14:28:09 2004 *************** *** 0 **** --- 1,17 ---- + ; RUN: llvm-as < %s | opt -constprop | llvm-dis | not grep call + + declare double %cos(double) + declare double %sin(double) + declare double %tan(double) + declare double %sqrt(double) + + double %T() { + %A = call double %cos(double 0.0) + %B = call double %sin(double 0.0) + %a = add double %A, %B + %C = call double %tan(double 0.0) + %b = add double %a, %C + %D = call double %sqrt(double 4.0) + %c = add double %b, %D + ret double %c + } From lattner at cs.uiuc.edu Tue Apr 13 14:29:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 14:29:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/ConstantProp.cpp Message-ID: <200404131928.OAA00918@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: ConstantProp.cpp updated: 1.46 -> 1.47 --- Log message: Constant propagation should remove the dead instructions --- Diffs of the changes: (+4 -0) Index: llvm/lib/Transforms/Scalar/ConstantProp.cpp diff -u llvm/lib/Transforms/Scalar/ConstantProp.cpp:1.46 llvm/lib/Transforms/Scalar/ConstantProp.cpp:1.47 --- llvm/lib/Transforms/Scalar/ConstantProp.cpp:1.46 Mon Jan 12 13:15:20 2004 +++ llvm/lib/Transforms/Scalar/ConstantProp.cpp Tue Apr 13 14:28:20 2004 @@ -67,6 +67,10 @@ // Replace all of the uses of a variable with uses of the constant. I->replaceAllUsesWith(C); + // Remove the dead instruction. + WorkList.erase(I); + I->getParent()->getInstList().erase(I); + // We made a change to the function... Changed = true; ++NumInstKilled; From lattner at cs.uiuc.edu Tue Apr 13 14:29:06 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 14:29:06 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/Utils/Local.h Message-ID: <200404131928.OAA02213@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms/Utils: Local.h updated: 1.16 -> 1.17 --- Log message: Add new interfaces --- Diffs of the changes: (+9 -0) Index: llvm/include/llvm/Transforms/Utils/Local.h diff -u llvm/include/llvm/Transforms/Utils/Local.h:1.16 llvm/include/llvm/Transforms/Utils/Local.h:1.17 --- llvm/include/llvm/Transforms/Utils/Local.h:1.16 Tue Mar 16 19:29:36 2004 +++ llvm/include/llvm/Transforms/Utils/Local.h Tue Apr 13 14:28:32 2004 @@ -47,6 +47,15 @@ Constant *ConstantFoldInstruction(Instruction *I); +/// canConstantFoldCallTo - Return true if its even possible to fold a call to +/// the specified function. +bool canConstantFoldCallTo(Function *F); + +/// ConstantFoldCall - Attempt to constant fold a call to the specified function +/// with the specified arguments, returning null if unsuccessful. +Constant *ConstantFoldCall(Function *F, const std::vector &Operands); + + //===----------------------------------------------------------------------===// // Local dead code elimination... // From lattner at cs.uiuc.edu Tue Apr 13 14:29:11 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 14:29:11 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/Local.cpp Message-ID: <200404131929.OAA07834@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: Local.cpp updated: 1.18 -> 1.19 --- Log message: Add a simple call constant propagation interface. --- Diffs of the changes: (+51 -0) Index: llvm/lib/Transforms/Utils/Local.cpp diff -u llvm/lib/Transforms/Utils/Local.cpp:1.18 llvm/lib/Transforms/Utils/Local.cpp:1.19 --- llvm/lib/Transforms/Utils/Local.cpp:1.18 Thu Mar 11 23:53:03 2004 +++ llvm/lib/Transforms/Utils/Local.cpp Tue Apr 13 14:28:52 2004 @@ -57,6 +57,18 @@ // If we reach here, all incoming values are the same constant. return Result; + } else if (CallInst *CI = dyn_cast(I)) { + if (Function *F = CI->getCalledFunction()) + if (canConstantFoldCallTo(F)) { + std::vector Args; + for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) + if (Constant *Op = dyn_cast(CI->getOperand(i))) + Args.push_back(Op); + else + return 0; + return ConstantFoldCall(F, Args); + } + return 0; } Constant *Op0 = 0, *Op1 = 0; @@ -215,6 +227,45 @@ } return false; } + +/// canConstantFoldCallTo - Return true if its even possible to fold a call to +/// the specified function. +bool llvm::canConstantFoldCallTo(Function *F) { + const std::string &Name = F->getName(); + return Name == "sin" || Name == "cos" || Name == "tan" || Name == "sqrt"; +} + +/// ConstantFoldCall - Attempt to constant fold a call to the specified function +/// with the specified arguments, returning null if unsuccessful. +Constant *llvm::ConstantFoldCall(Function *F, + const std::vector &Operands) { + const std::string &Name = F->getName(); + const Type *Ty = F->getReturnType(); + + if (Name == "sin") { + if (Operands.size() == 1) + if (ConstantFP *CFP = dyn_cast(Operands[0])) + return ConstantFP::get(Ty, sin(CFP->getValue())); + + } else if (Name == "cos") { + if (Operands.size() == 1) + if (ConstantFP *CFP = dyn_cast(Operands[0])) + return ConstantFP::get(Ty, cos(CFP->getValue())); + + } else if (Name == "tan") { + if (Operands.size() == 1) + if (ConstantFP *CFP = dyn_cast(Operands[0])) + return ConstantFP::get(Ty, tan(CFP->getValue())); + + } else if (Name == "sqrt") { + if (Operands.size() == 1) + if (ConstantFP *CFP = dyn_cast(Operands[0])) + if (CFP->getValue() >= 0) + return ConstantFP::get(Ty, sqrt(CFP->getValue())); + } + return 0; +} + From lattner at cs.uiuc.edu Tue Apr 13 14:44:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 14:44:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/SCCP/calltest.ll Message-ID: <200404131943.OAA17048@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/SCCP: calltest.ll added (r1.1) --- Log message: New testcase --- Diffs of the changes: (+24 -0) Index: llvm/test/Regression/Transforms/SCCP/calltest.ll diff -c /dev/null llvm/test/Regression/Transforms/SCCP/calltest.ll:1.1 *** /dev/null Tue Apr 13 14:43:43 2004 --- llvm/test/Regression/Transforms/SCCP/calltest.ll Tue Apr 13 14:43:33 2004 *************** *** 0 **** --- 1,24 ---- + ; RUN: llvm-as < %s | opt -sccp -adce -simplifycfg | llvm-dis | not grep br + + ; No matter how hard you try, sqrt(1.0) is always 1.0. This allows the + ; optimizer to delete this loop. + + declare double %sqrt(double) + + double %test(uint %param) { + entry: + br label %Loop + + Loop: + %I2 = phi uint [ 0, %entry ], [ %I3, %Loop ] + %V = phi double [ 1.0, %entry], [ %V2, %Loop ] + + %V2 = call double %sqrt(double %V) + + %I3 = add uint %I2, 1 + %tmp.7 = setne uint %I3, %param + br bool %tmp.7, label %Loop, label %Exit + + Exit: + ret double %V + } From lattner at cs.uiuc.edu Tue Apr 13 14:44:07 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 14:44:07 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/SCCP.cpp Message-ID: <200404131944.OAA17059@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: SCCP.cpp updated: 1.93 -> 1.94 --- Log message: Add SCCP support for constant folding calls, implementing: test/Regression/Transforms/SCCP/calltest.ll --- Diffs of the changes: (+33 -1) Index: llvm/lib/Transforms/Scalar/SCCP.cpp diff -u llvm/lib/Transforms/Scalar/SCCP.cpp:1.93 llvm/lib/Transforms/Scalar/SCCP.cpp:1.94 --- llvm/lib/Transforms/Scalar/SCCP.cpp:1.93 Sun Apr 4 20:29:05 2004 +++ llvm/lib/Transforms/Scalar/SCCP.cpp Tue Apr 13 14:43:54 2004 @@ -29,6 +29,7 @@ #include "llvm/Pass.h" #include "llvm/Type.h" #include "llvm/Support/InstVisitor.h" +#include "llvm/Transforms/Utils/Local.h" #include "Support/Debug.h" #include "Support/Statistic.h" #include "Support/STLExtras.h" @@ -220,7 +221,7 @@ void visitStoreInst (Instruction &I) { /*returns void*/ } void visitLoadInst (LoadInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); - void visitCallInst (Instruction &I) { markOverdefined(&I); } + void visitCallInst (CallInst &I); void visitInvokeInst (TerminatorInst &I) { if (I.getType() != Type::VoidTy) markOverdefined(&I); visitTerminatorInst(I); @@ -776,4 +777,35 @@ // Otherwise we cannot say for certain what value this load will produce. // Bail out. markOverdefined(IV, &I); +} + +void SCCP::visitCallInst(CallInst &I) { + InstVal &IV = ValueState[&I]; + if (IV.isOverdefined()) return; + + Function *F = I.getCalledFunction(); + if (F == 0 || !canConstantFoldCallTo(F)) { + markOverdefined(IV, &I); + return; + } + + std::vector Operands; + Operands.reserve(I.getNumOperands()-1); + + for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) { + InstVal &State = getValueState(I.getOperand(i)); + if (State.isUndefined()) + return; // Operands are not resolved yet... + else if (State.isOverdefined()) { + markOverdefined(IV, &I); + return; + } + assert(State.isConstant() && "Unknown state!"); + Operands.push_back(State.getConstant()); + } + + if (Constant *C = ConstantFoldCall(F, Operands)) + markConstant(IV, &I, C); + else + markOverdefined(IV, &I); } From lattner at cs.uiuc.edu Tue Apr 13 14:49:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 14:49:01 2004 Subject: [llvm-commits] CVS: llvm/docs/ExtendingLLVM.html Message-ID: <200404131949.OAA18044@zion.cs.uiuc.edu> Changes in directory llvm/docs: ExtendingLLVM.html updated: 1.4 -> 1.5 --- Log message: Add a note --- Diffs of the changes: (+5 -1) Index: llvm/docs/ExtendingLLVM.html diff -u llvm/docs/ExtendingLLVM.html:1.4 llvm/docs/ExtendingLLVM.html:1.5 --- llvm/docs/ExtendingLLVM.html:1.4 Sat Apr 10 01:56:53 2004 +++ llvm/docs/ExtendingLLVM.html Tue Apr 13 14:48:55 2004 @@ -104,6 +104,10 @@ not access memory, or does not write to memory, add it to the relevant list of functions. +
    1. llvm/lib/Transforms/Utils/Local.cpp: If it is possible to constant + propagate your intrinsic, add support to it in the + canConstantFoldCallTo and ConstantFoldCall functions.
    2. +
    3. Test your intrinsic
    4. llvm/test/Regression/*: add your test cases to the test suite.
    @@ -227,7 +231,7 @@ Misha Brukman
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/04/10 06:56:53 $ + Last modified: $Date: 2004/04/13 19:48:55 $ From lattner at cs.uiuc.edu Tue Apr 13 15:55:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 15:55:02 2004 Subject: [llvm-commits] CVS: llvm/utils/fpcmp/ Message-ID: <200404132055.PAA28798@zion.cs.uiuc.edu> Changes in directory llvm/utils/fpcmp: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/utils/fpcmp added to the repository --- Diffs of the changes: (+0 -0) From lattner at cs.uiuc.edu Tue Apr 13 15:56:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 15:56:02 2004 Subject: [llvm-commits] CVS: llvm/utils/fpcmp/Makefile fpcmp.cpp Message-ID: <200404132055.PAA28812@zion.cs.uiuc.edu> Changes in directory llvm/utils/fpcmp: Makefile added (r1.1) fpcmp.cpp added (r1.1) --- Log message: Okay, spiff is completely incapable of handling files of nontrivial size. Here is a simple minimal program that does what we want. Instead of taking minutes to compare mesa's output, and crashing on binary files (like spiff does), this take < .02s in the common case and doesn't crash. --- Diffs of the changes: (+171 -0) Index: llvm/utils/fpcmp/Makefile diff -c /dev/null llvm/utils/fpcmp/Makefile:1.1 *** /dev/null Tue Apr 13 15:55:59 2004 --- llvm/utils/fpcmp/Makefile Tue Apr 13 15:55:49 2004 *************** *** 0 **** --- 1,15 ---- + ##===- utils/fpcmp/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 = ../.. + TOOLNAME = fpcmp + USEDLIBS = support.a + + include $(LEVEL)/Makefile.common + Index: llvm/utils/fpcmp/fpcmp.cpp diff -c /dev/null llvm/utils/fpcmp/fpcmp.cpp:1.1 *** /dev/null Tue Apr 13 15:55:59 2004 --- llvm/utils/fpcmp/fpcmp.cpp Tue Apr 13 15:55:49 2004 *************** *** 0 **** --- 1,156 ---- + //===- fpcmp.cpp - A fuzzy "cmp" that permits floating point noise --------===// + // + // 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. + // + //===----------------------------------------------------------------------===// + // + // fpcmp is a tool that basically works like the 'cmp' tool, except that it can + // tolerate errors due to floating point noise, with the -r option. + // + //===----------------------------------------------------------------------===// + + #include "Support/CommandLine.h" + #include "Support/FileUtilities.h" + #include "Config/fcntl.h" + #include "Config/sys/mman.h" + #include + #include + + using namespace llvm; + + namespace { + cl::opt + File1(cl::Positional, cl::desc(""), cl::Required); + cl::opt + File2(cl::Positional, cl::desc(""), cl::Required); + + cl::opt + RelTolerance("r", cl::desc("Relative error tolerated"), cl::init(0)); + cl::opt + AbsTolerance("a", cl::desc("Absolute error tolerated"), cl::init(0)); + } + + + /// OpenFile - mmap the specified file into the address space for reading, and + /// return the length and address of the buffer. + static void OpenFile(const std::string &Filename, unsigned &Len, char* &BufPtr){ + int FD = open(Filename.c_str(), O_RDONLY); + if (FD == -1 || (Len = getFileSize(Filename)) == ~0U) { + std::cerr << "Error: cannot open file '" << Filename << "'\n"; + exit(2); + } + + // mmap in the file all at once... + BufPtr = (char*)mmap(0, Len, PROT_READ, MAP_PRIVATE, FD, 0); + + if (BufPtr == (char*)MAP_FAILED) { + std::cerr << "Error: cannot open file '" << Filename << "'\n"; + exit(2); + } + } + + static bool isNumberChar(char C) { + switch (C) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case '.': + case 'e': + case 'E': return true; + default: return false; + } + } + + static char *BackupNumber(char *Pos, char *FirstChar) { + while (Pos < FirstChar && isNumberChar(Pos[-1])) + --Pos; + return Pos; + } + + static void CompareNumbers(char *&F1P, char *&F2P, char *F1End, char *F2End) { + char *F1NumEnd, *F2NumEnd; + double V1 = strtod(F1P, &F1NumEnd); + double V2 = strtod(F2P, &F2NumEnd); + + if (F1NumEnd == F1P || F2NumEnd == F2P) { + std::cerr << "Comparison failed, not a numeric difference.\n"; + exit(1); + } + + // Check to see if these are inside the absolute tolerance + if (AbsTolerance < std::abs(V1-V2)) { + // Nope, check the relative tolerance... + double Diff; + if (V2) + Diff = std::abs(V1/V2 - 1.0); + else if (V1) + Diff = std::abs(V2/V1 - 1.0); + else + Diff = 0; // Both zero. + if (Diff > RelTolerance) { + std::cerr << "Compared: " << V1 << " and " << V2 << ": diff = " + << Diff << "\n"; + std::cerr << "Out of tolerence: rel/abs: " << RelTolerance + << "/" << AbsTolerance << "\n"; + exit(1); + } + } + + // Otherwise, advance our read pointers to the end of the numbers. + F1P = F1NumEnd; F2P = F2NumEnd; + } + + + int main(int argc, char **argv) { + cl::ParseCommandLineOptions(argc, argv); + + // mmap in the files. + unsigned File1Len, File2Len; + char *File1Start, *File2Start; + OpenFile(File1, File1Len, File1Start); + OpenFile(File2, File2Len, File2Start); + + // Okay, now that we opened the files, scan them for the first difference. + char *File1End = File1Start+File1Len; + char *File2End = File2Start+File2Len; + char *F1P = File1Start; + char *F2P = File2Start; + + while (1) { + // Scan for the end of file or first difference. + while (F1P < File1End && F2P < File2End && *F1P == *F2P) + ++F1P, ++F2P; + + if (F1P >= File1End || F2P >= File2End) break; + + // Okay, we must have found a difference. Backup to the start of the + // current number each stream is at so that we can compare from the + // beginning. + F1P = BackupNumber(F1P, File1Start); + F2P = BackupNumber(F2P, File2Start); + + // Now that we are at the start of the numbers, compare them, exiting if + // they don't match. + CompareNumbers(F1P, F2P, File1End, File2End); + } + + // Okay, we reached the end of file. If both files are at the end, we + // succeeded. + if (F1P >= File1End && F2P >= File2End) return 0; + + // Otherwise, we might have run off the end due to a number, backup and retry. + F1P = BackupNumber(F1P, File1Start); + F2P = BackupNumber(F2P, File2Start); + + // Now that we are at the start of the numbers, compare them, exiting if + // they don't match. + CompareNumbers(F1P, F2P, File1End, File2End); + + // If we found the end, we succeeded. + if (F1P >= File1End && F2P >= File2End) return 0; + + return 1; + } + From lattner at cs.uiuc.edu Tue Apr 13 15:59:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 15:59:01 2004 Subject: [llvm-commits] CVS: llvm/utils/Spiff/LICENSE.TXT Makefile README command.c command.h comment.c comment.h compare.c compare.h edit.h exact.c exact.h flagdefs.h float.c float.h floatrep.c floatrep.h line.c line.h miller.c miller.h misc.c misc.h output.c output.h paper.ms parse.c parse.h spiff.1 spiff.c strings.c strings.h token.c token.h tol.c tol.h visual.c visual.h Message-ID: <200404132059.PAA29072@zion.cs.uiuc.edu> Changes in directory llvm/utils/Spiff: LICENSE.TXT (r1.1) removed Makefile (r1.2) removed README (r1.1) removed command.c (r1.1) removed command.h (r1.1) removed comment.c (r1.2) removed comment.h (r1.2) removed compare.c (r1.2) removed compare.h (r1.1) removed edit.h (r1.1) removed exact.c (r1.2) removed exact.h (r1.1) removed flagdefs.h (r1.1) removed float.c (r1.2) removed float.h (r1.2) removed floatrep.c (r1.2) removed floatrep.h (r1.1) removed line.c (r1.2) removed line.h (r1.3) removed miller.c (r1.2) removed miller.h (r1.1) removed misc.c (r1.2) removed misc.h (r1.1) removed output.c (r1.3) removed output.h (r1.1) removed paper.ms (r1.1) removed parse.c (r1.2) removed parse.h (r1.1) removed spiff.1 (r1.1) removed spiff.c (r1.2) removed strings.c (r1.2) removed strings.h (r1.2) removed token.c (r1.1) removed token.h (r1.1) removed tol.c (r1.2) removed tol.h (r1.2) removed visual.c (r1.2) removed visual.h (r1.1) removed --- Log message: Remove spiff. Though it looked good, it was not really as spiffy as it seemed --- Diffs of the changes: (+0 -0) From lattner at cs.uiuc.edu Tue Apr 13 16:00:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 16:00:01 2004 Subject: [llvm-commits] CVS: llvm/utils/Makefile Message-ID: <200404132059.PAA29089@zion.cs.uiuc.edu> Changes in directory llvm/utils: Makefile updated: 1.5 -> 1.6 --- Log message: Out with spiff, in with fpcmp --- Diffs of the changes: (+3 -3) Index: llvm/utils/Makefile diff -u llvm/utils/Makefile:1.5 llvm/utils/Makefile:1.6 --- llvm/utils/Makefile:1.5 Mon Apr 12 17:53:51 2004 +++ llvm/utils/Makefile Tue Apr 13 15:59:24 2004 @@ -1,4 +1,4 @@ -##===- utils/Makefile ------------------------------*- Makefile -*-===## +##===- utils/Makefile --------------------------------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # @@ -6,9 +6,9 @@ # the University of Illinois Open Source License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## -LEVEL = .. -DIRS = Burg TableGen Spiff +LEVEL = .. +DIRS = Burg TableGen fpcmp include $(LEVEL)/Makefile.common From lattner at cs.uiuc.edu Tue Apr 13 16:00:06 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 16:00:06 2004 Subject: [llvm-commits] CVS: llvm/LICENSE.TXT Message-ID: <200404132059.PAA29135@zion.cs.uiuc.edu> Changes in directory llvm: LICENSE.TXT updated: 1.15 -> 1.16 --- Log message: We actually don't have spiff anymore --- Diffs of the changes: (+0 -1) Index: llvm/LICENSE.TXT diff -u llvm/LICENSE.TXT:1.15 llvm/LICENSE.TXT:1.16 --- llvm/LICENSE.TXT:1.15 Tue Apr 13 08:42:38 2004 +++ llvm/LICENSE.TXT Tue Apr 13 15:59:47 2004 @@ -66,7 +66,6 @@ llvm/projects/sample/autoconf Burg: llvm/utils/Burg llvm/test/Programs/MultiSource/Applications/Burg -Spiff: llvm/utils/Spiff Aha: llvm/test/Programs/MultiSource/Applications/aha SGEFA: llvm/test/Programs/MultiSource/Applications/sgefa SIOD: llvm/test/Programs/MultiSource/Applications/siod From lattner at cs.uiuc.edu Tue Apr 13 16:01:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 16:01:00 2004 Subject: [llvm-commits] CVS: llvm/test/Programs/External/SPEC/CFP2000/177.mesa/Makefile Message-ID: <200404132101.QAA29366@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/External/SPEC/CFP2000/177.mesa: Makefile updated: 1.3 -> 1.4 --- Log message: Allow mesa to pass finally --- Diffs of the changes: (+2 -0) Index: llvm/test/Programs/External/SPEC/CFP2000/177.mesa/Makefile diff -u llvm/test/Programs/External/SPEC/CFP2000/177.mesa/Makefile:1.3 llvm/test/Programs/External/SPEC/CFP2000/177.mesa/Makefile:1.4 --- llvm/test/Programs/External/SPEC/CFP2000/177.mesa/Makefile:1.3 Wed Feb 25 18:01:21 2004 +++ llvm/test/Programs/External/SPEC/CFP2000/177.mesa/Makefile Tue Apr 13 16:00:52 2004 @@ -1,4 +1,6 @@ LEVEL = ../../../../../.. +FP_ABSTOLERANCE := 4 + ifdef LARGE_PROBLEM_SIZE RUN_OPTIONS := -frames 500 else From lattner at cs.uiuc.edu Tue Apr 13 16:02:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 16:02:01 2004 Subject: [llvm-commits] CVS: llvm/test/Programs/Makefile.programs Message-ID: <200404132101.QAA29440@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs: Makefile.programs updated: 1.126 -> 1.127 --- Log message: switch to using fpcmp instead of spiff, which really wasn't spiffy. --- Diffs of the changes: (+6 -2) Index: llvm/test/Programs/Makefile.programs diff -u llvm/test/Programs/Makefile.programs:1.126 llvm/test/Programs/Makefile.programs:1.127 --- llvm/test/Programs/Makefile.programs:1.126 Tue Apr 13 13:28:12 2004 +++ llvm/test/Programs/Makefile.programs Tue Apr 13 16:01:13 2004 @@ -57,11 +57,15 @@ TOLERANCEOPT := ifdef FP_TOLERANCE -TOLERANCEOPT := -r$(FP_TOLERANCE) +TOLERANCEOPT := -r $(FP_TOLERANCE) +else +ifdef FP_ABSTOLERANCE +TOLERANCEOPT := -a $(FP_ABSTOLERANCE) +endif endif # DIFFPROG - The program used to diff the output -DIFFPROG := $(PROGDIR)/DiffOutput.sh "$(LLVMTOOLCURRENT)/spiff $(TOLERANCEOPT)" +DIFFPROG := $(PROGDIR)/DiffOutput.sh "$(LLVMTOOLCURRENT)/fpcmp $(TOLERANCEOPT)" # RUNTIMELIMIT - The number of seconds we should wait before certain events # timeout. This is overridable on the commandline or in tests makefiles. From gaeke at cs.uiuc.edu Tue Apr 13 16:30:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Apr 13 16:30:01 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/ReoptimizerInternal.h Message-ID: <200404132129.QAA00949@seraph.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: ReoptimizerInternal.h updated: 1.2 -> 1.3 --- Log message: Provide an external declaration of createTraceOptEmitter(). --- Diffs of the changes: (+6 -0) Index: reopt/lib/LightWtProfiling/ReoptimizerInternal.h diff -u reopt/lib/LightWtProfiling/ReoptimizerInternal.h:1.2 reopt/lib/LightWtProfiling/ReoptimizerInternal.h:1.3 --- reopt/lib/LightWtProfiling/ReoptimizerInternal.h:1.2 Wed Jan 14 17:02:22 2004 +++ reopt/lib/LightWtProfiling/ReoptimizerInternal.h Tue Apr 13 16:29:41 2004 @@ -19,6 +19,8 @@ #define REOPTIMIZERINTERNAL_H #include "Support/DataTypes.h" +#include "llvm/CodeGen/MachineCodeEmitter.h" +#include "llvm/Target/TargetData.h" #include #include @@ -148,6 +150,10 @@ bool initialize_timer (); extern uint64_t llvm_interval_counter; + +// TraceOptEmitter.cpp ////////////////////////////////////////////////// + +MachineCodeEmitter *createTraceOptEmitter(const TargetData &TD); }; // end namespace llvm From gaeke at cs.uiuc.edu Tue Apr 13 16:30:08 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Apr 13 16:30:08 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp Message-ID: <200404132129.QAA00956@seraph.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: RuntimeOptimizations.cpp updated: 1.24 -> 1.25 --- Log message: Include MachineCodeEmitter.h and TargetData.h. Construct a TraceOptEmitter and provide it to the machine-code emission passes. --- Diffs of the changes: (+5 -2) Index: reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp diff -u reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.24 reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.25 --- reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.24 Thu Apr 8 15:30:50 2004 +++ reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp Tue Apr 13 16:29:43 2004 @@ -21,11 +21,13 @@ #include "llvm/Assembly/PrintModulePass.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/IntrinsicLowering.h" #include "llvm/ModuleProvider.h" #include "llvm/PassManager.h" #include "llvm/Target/TargetJITInfo.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachineImpls.h" namespace llvm { @@ -80,8 +82,9 @@ PM.add (createUnpackTraceFunctionPass (Target, TF)); DEBUG(PM.add (createMachineFunctionPrinterPass (&std::cerr, "After unpacking:\n"))); Target->getJITInfo ()->addPassesToJITCompile (PM); - // FIXME: We need the JIT's MachineCodeEmitter - // Target->addPassesToEmitMachineCode (PM, MCE); + const TargetData &TD = Target->getTargetData (); + MachineCodeEmitter *MCE = createTraceOptEmitter (TD); + Target->addPassesToEmitMachineCode (PM, *MCE); PM.run (*TF->TraceFn); // Add a branch from the entry basic block of the trace in the MatrixFn to the From gaeke at cs.uiuc.edu Tue Apr 13 16:30:13 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Tue Apr 13 16:30:13 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/TraceOptEmitter.cpp Message-ID: <200404132129.QAA00963@seraph.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: TraceOptEmitter.cpp updated: 1.1 -> 1.2 --- Log message: Constify the TargetData object that we're using. Add a comment about stubs. --- Diffs of the changes: (+7 -3) Index: reopt/lib/LightWtProfiling/TraceOptEmitter.cpp diff -u reopt/lib/LightWtProfiling/TraceOptEmitter.cpp:1.1 reopt/lib/LightWtProfiling/TraceOptEmitter.cpp:1.2 --- reopt/lib/LightWtProfiling/TraceOptEmitter.cpp:1.1 Mon Apr 12 15:57:43 2004 +++ reopt/lib/LightWtProfiling/TraceOptEmitter.cpp Tue Apr 13 16:29:44 2004 @@ -10,6 +10,10 @@ // The trace reoptimizer uses this MachineCodeEmitter to output // optimized machine code to memory, so that it can be executed instead of // the corresponding unoptimized code. +// +// We do not need to support function stubs in this Emitter because +// with the current Reoptimizer, there can never be any references in a +// trace to functions which have not yet been compiled. // // Currently, it uses the same executable memory segment that the // TraceCache would use, but the TraceCache is unaware of it, so they can @@ -33,7 +37,7 @@ /// which is used to output functions to memory for execution. /// class TraceOptEmitter : public MachineCodeEmitter { - TargetData &TD; + const TargetData &TD; // CurBlock - The start of the current block of memory. CurByte - The // current byte being emitted to. @@ -44,7 +48,7 @@ // constant pool. std::vector ConstantPoolAddresses; public: - TraceOptEmitter (TargetData &_TD) : TD (_TD) { + TraceOptEmitter (const TargetData &_TD) : TD (_TD) { // Re-use the existing DummyFunction area for code emission in the // Reoptimizer. No memory is reserved for stubs. FunctionBase = (unsigned char *) dummyFunction2; @@ -78,7 +82,7 @@ }; } -MachineCodeEmitter *createTraceOptEmitter(TargetData &TD) { +MachineCodeEmitter *createTraceOptEmitter(const TargetData &TD) { return new TraceOptEmitter(TD); } From lattner at cs.uiuc.edu Tue Apr 13 16:45:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 16:45:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/2004-04-13-FPCMOV-Crash.llx Message-ID: <200404132145.QAA32474@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: 2004-04-13-FPCMOV-Crash.llx added (r1.1) --- Log message: new testcase that crashes the fp stackifier --- Diffs of the changes: (+8 -0) Index: llvm/test/Regression/CodeGen/X86/2004-04-13-FPCMOV-Crash.llx diff -c /dev/null llvm/test/Regression/CodeGen/X86/2004-04-13-FPCMOV-Crash.llx:1.1 *** /dev/null Tue Apr 13 16:45:04 2004 --- llvm/test/Regression/CodeGen/X86/2004-04-13-FPCMOV-Crash.llx Tue Apr 13 16:44:54 2004 *************** *** 0 **** --- 1,8 ---- + ; RUN: llvm-as < %s | llc -march=x86 + + implementation ; Functions: + + double %test(double %d) { + %X = select bool false, double %d, double %d ; [#uses=0] + ret double %X + } From lattner at cs.uiuc.edu Tue Apr 13 16:49:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 16:49:00 2004 Subject: [llvm-commits] CVS: llvm/test/Programs/External/SPEC/CINT2000/252.eon/Makefile Message-ID: <200404132148.QAA14773@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/External/SPEC/CINT2000/252.eon: Makefile updated: 1.7 -> 1.8 --- Log message: Allow eon to pass --- Diffs of the changes: (+1 -0) Index: llvm/test/Programs/External/SPEC/CINT2000/252.eon/Makefile diff -u llvm/test/Programs/External/SPEC/CINT2000/252.eon/Makefile:1.7 llvm/test/Programs/External/SPEC/CINT2000/252.eon/Makefile:1.8 --- llvm/test/Programs/External/SPEC/CINT2000/252.eon/Makefile:1.7 Wed Feb 25 18:01:20 2004 +++ llvm/test/Programs/External/SPEC/CINT2000/252.eon/Makefile Tue Apr 13 16:48:26 2004 @@ -2,6 +2,7 @@ RUN_OPTIONS = chair.control.cook chair.camera chair.surfaces chair.cook.ppm ppm pixels_out.cook STDOUT_FILENAME = cook_log.out STDERR_FILENAME = cook_log.err +FP_TOLERANCE := 0.0001 # Yes, we know this is an old crufty C++ benchmark. Don't tell us about it GCC! CPPFLAGS = -Wno-deprecated -Wno-non-template-friend -DHAS_ERRLIST -DUSE_STRERROR -DSPEC_STDCPP -DNDEBUG From lattner at cs.uiuc.edu Tue Apr 13 16:49:06 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 16:49:06 2004 Subject: [llvm-commits] CVS: llvm/utils/fpcmp/fpcmp.cpp Message-ID: <200404132148.QAA14784@zion.cs.uiuc.edu> Changes in directory llvm/utils/fpcmp: fpcmp.cpp updated: 1.1 -> 1.2 --- Log message: Fix bug, add support for +/- --- Diffs of the changes: (+2 -2) Index: llvm/utils/fpcmp/fpcmp.cpp diff -u llvm/utils/fpcmp/fpcmp.cpp:1.1 llvm/utils/fpcmp/fpcmp.cpp:1.2 --- llvm/utils/fpcmp/fpcmp.cpp:1.1 Tue Apr 13 15:55:49 2004 +++ llvm/utils/fpcmp/fpcmp.cpp Tue Apr 13 16:48:43 2004 @@ -56,7 +56,7 @@ switch (C) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - case '.': + case '.': case '+': case '-': case 'e': case 'E': return true; default: return false; @@ -64,7 +64,7 @@ } static char *BackupNumber(char *Pos, char *FirstChar) { - while (Pos < FirstChar && isNumberChar(Pos[-1])) + while (Pos > FirstChar && isNumberChar(Pos[-1])) --Pos; return Pos; } From lattner at cs.uiuc.edu Tue Apr 13 16:56:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 16:56:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200404132156.QAA07360@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.235 -> 1.236 --- Log message: Implement a small optimization, which papers over the problem in X86/2004-04-13-FPCMOV-Crash.llx A more robust fix is to follow. --- Diffs of the changes: (+12 -3) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.235 llvm/lib/Target/X86/InstSelectSimple.cpp:1.236 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.235 Tue Apr 13 12:20:37 2004 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Tue Apr 13 16:56:09 2004 @@ -1038,7 +1038,18 @@ FalseVal = ConstantExpr::getCast(F, Type::ShortTy); } - + unsigned TrueReg = getReg(TrueVal, MBB, IP); + unsigned FalseReg = getReg(FalseVal, MBB, IP); + if (TrueReg == FalseReg) { + static const unsigned Opcode[] = { + X86::MOV8rr, X86::MOV16rr, X86::MOV32rr, X86::FpMOV, X86::MOV32rr + }; + BuildMI(*MBB, IP, Opcode[SelectClass], 1, DestReg).addReg(TrueReg); + if (SelectClass == cLong) + BuildMI(*MBB, IP, X86::MOV32rr, 1, DestReg+1).addReg(TrueReg+1); + return; + } + unsigned Opcode; if (SetCondInst *SCI = canFoldSetCCIntoBranchOrSelect(Cond)) { // We successfully folded the setcc into the select instruction. @@ -1130,8 +1141,6 @@ } } - unsigned TrueReg = getReg(TrueVal, MBB, IP); - unsigned FalseReg = getReg(FalseVal, MBB, IP); unsigned RealDestReg = DestReg; From criswell at cs.uiuc.edu Tue Apr 13 17:14:01 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Tue Apr 13 17:14:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200404132213.RAA27560@choi.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.236 -> 1.237 --- Log message: Added support for the llvm.readio and llvm.writeio intrinsics. On x86, memory operations occur in-order, so these are just lowered into volatile loads and stores. --- Diffs of the changes: (+29 -0) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.236 llvm/lib/Target/X86/InstSelectSimple.cpp:1.237 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.236 Tue Apr 13 16:56:09 2004 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Tue Apr 13 17:13:14 2004 @@ -1541,6 +1541,35 @@ case Intrinsic::writeport: // We directly implement these intrinsics break; + case Intrinsic::readio: { + // On X86, memory operations are in-order. Lower this intrinsic + // into a volatile load. + Instruction *Before = CI->getPrev(); + LoadInst * LI = new LoadInst (CI->getOperand(1), "", true, CI); + CI->replaceAllUsesWith (LI); + BB->getInstList().erase (CI); + if (Before) { // Move iterator to instruction after call + I = Before; ++I; + } else { + I = BB->begin(); + } + break; + } + case Intrinsic::writeio: { + // On X86, memory operations are in-order. Lower this intrinsic + // into a volatile store. + Instruction *Before = CI->getPrev(); + StoreInst * LI = new StoreInst (CI->getOperand(1), + CI->getOperand(2), true, CI); + CI->replaceAllUsesWith (LI); + BB->getInstList().erase (CI); + if (Before) { // Move iterator to instruction after call + I = Before; ++I; + } else { + I = BB->begin(); + } + break; + } default: // All other intrinsic calls we must lower. Instruction *Before = CI->getPrev(); From lattner at cs.uiuc.edu Tue Apr 13 21:23:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 21:23:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Intrinsics.h Message-ID: <200404140223.VAA29255@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Intrinsics.h updated: 1.20 -> 1.21 --- Log message: Temporarily hack in the intrinsics that John added. I expect him to finish up their addition, but in the meantime, the build should not be broken. --- Diffs of the changes: (+2 -0) Index: llvm/include/llvm/Intrinsics.h diff -u llvm/include/llvm/Intrinsics.h:1.20 llvm/include/llvm/Intrinsics.h:1.21 --- llvm/include/llvm/Intrinsics.h:1.20 Thu Apr 8 15:26:21 2004 +++ llvm/include/llvm/Intrinsics.h Tue Apr 13 21:22:54 2004 @@ -60,6 +60,8 @@ // Input/Output intrinsics readport, writeport, + readio, + writeio, //===------------------------------------------------------------------===// // This section defines intrinsic functions used to represent Alpha From lattner at cs.uiuc.edu Tue Apr 13 21:43:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 21:43:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/FloatingPoint.cpp Message-ID: <200404140242.VAA29771@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: FloatingPoint.cpp updated: 1.30 -> 1.31 --- Log message: This is the real fix for Codegen/X86/2004-04-13-FPCMOV-Crash.llx which works even when the "optimization" I added before is turned off. It generates this extremely pointless code: test: fld QWORD PTR [%ESP + 4] mov %AL, 0 test %AL, %AL fcmove %ST(0), %ST(0) ret Good thing the optimizer will have removed this before code generation anyway. :) --- Diffs of the changes: (+8 -7) Index: llvm/lib/Target/X86/FloatingPoint.cpp diff -u llvm/lib/Target/X86/FloatingPoint.cpp:1.30 llvm/lib/Target/X86/FloatingPoint.cpp:1.31 --- llvm/lib/Target/X86/FloatingPoint.cpp:1.30 Sun Apr 11 22:02:48 2004 +++ llvm/lib/Target/X86/FloatingPoint.cpp Tue Apr 13 21:42:32 2004 @@ -682,13 +682,14 @@ MI->getOperand(0).setReg(getSTReg(Op1)); // If we kill the second operand, make sure to pop it from the stack. - for (LiveVariables::killed_iterator KI = LV->killed_begin(MI), - E = LV->killed_end(MI); KI != E; ++KI) - if (KI->second == X86::FP0+Op1) { - // Get this value off of the register stack. - freeStackSlotAfter(I, Op1); - break; - } + if (Op0 != Op1) + for (LiveVariables::killed_iterator KI = LV->killed_begin(MI), + E = LV->killed_end(MI); KI != E; ++KI) + if (KI->second == X86::FP0+Op1) { + // Get this value off of the register stack. + freeStackSlotAfter(I, Op1); + break; + } } From lattner at cs.uiuc.edu Tue Apr 13 22:29:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 22:29:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200404140328.WAA05991@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.189 -> 1.190 --- Log message: ADd a trivial instcombine: load null -> null --- Diffs of the changes: (+5 -2) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.189 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.190 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.189 Sat Apr 10 20:39:19 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Tue Apr 13 22:28:36 2004 @@ -2853,8 +2853,11 @@ Value *Op = LI.getOperand(0); if (LI.isVolatile()) return 0; - if (ConstantPointerRef *CPR = dyn_cast(Op)) - Op = CPR->getValue(); + if (Constant *C = dyn_cast(Op)) + if (C->isNullValue()) // load null -> 0 + return ReplaceInstUsesWith(LI, Constant::getNullValue(LI.getType())); + else if (ConstantPointerRef *CPR = dyn_cast(C)) + Op = CPR->getValue(); // Instcombine load (constant global) into the value loaded... if (GlobalVariable *GV = dyn_cast(Op)) From lattner at cs.uiuc.edu Tue Apr 13 22:33:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Apr 13 22:33:01 2004 Subject: [llvm-commits] CVS: llvm/test/Programs/SingleSource/Benchmarks/Misc/Makefile pi.c Message-ID: <200404140332.WAA06465@zion.cs.uiuc.edu> Changes in directory llvm/test/Programs/SingleSource/Benchmarks/Misc: Makefile updated: 1.1 -> 1.2 pi.c updated: 1.4 -> 1.5 --- Log message: Changes to allow pi to pass --- Diffs of the changes: (+2 -1) Index: llvm/test/Programs/SingleSource/Benchmarks/Misc/Makefile diff -u llvm/test/Programs/SingleSource/Benchmarks/Misc/Makefile:1.1 llvm/test/Programs/SingleSource/Benchmarks/Misc/Makefile:1.2 --- llvm/test/Programs/SingleSource/Benchmarks/Misc/Makefile:1.1 Thu Sep 11 12:58:24 2003 +++ llvm/test/Programs/SingleSource/Benchmarks/Misc/Makefile Tue Apr 13 22:32:46 2004 @@ -1,4 +1,5 @@ LEVEL = ../../../../.. LDFLAGS += -lm +FP_TOLERANCE := 0.001 include $(LEVEL)/test/Programs/SingleSource/Makefile.singlesrc Index: llvm/test/Programs/SingleSource/Benchmarks/Misc/pi.c diff -u llvm/test/Programs/SingleSource/Benchmarks/Misc/pi.c:1.4 llvm/test/Programs/SingleSource/Benchmarks/Misc/pi.c:1.5 --- llvm/test/Programs/SingleSource/Benchmarks/Misc/pi.c:1.4 Sun Feb 29 21:41:00 2004 +++ llvm/test/Programs/SingleSource/Benchmarks/Misc/pi.c Tue Apr 13 22:32:46 2004 @@ -55,6 +55,6 @@ } printf(" x = %9.6f y = %12.2f low = %8d j = %7d\n",x,y,(int)low,(int)j); pi = 4.0 * (float)low/(float)itot; - printf("Pi = %9.6f ztot = %12.2f itot = %8d\n",pi,ztot,(int)itot); + printf("Pi = %9.6f ztot = %12.2f itot = %8d\n",pi,ztot*0.0,(int)itot); return 0; } From criswell at cs.uiuc.edu Wed Apr 14 08:48:04 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Wed Apr 14 08:48:04 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Function.cpp Verifier.cpp Message-ID: <200404141347.IAA28636@choi.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Function.cpp updated: 1.67 -> 1.68 Verifier.cpp updated: 1.92 -> 1.93 --- Log message: Finish adding the llvm.readio and llvm.writeio intrinsics. Sorry these didn't get in yesterday. --- Diffs of the changes: (+24 -0) Index: llvm/lib/VMCore/Function.cpp diff -u llvm/lib/VMCore/Function.cpp:1.67 llvm/lib/VMCore/Function.cpp:1.68 --- llvm/lib/VMCore/Function.cpp:1.67 Thu Apr 8 15:27:38 2004 +++ llvm/lib/VMCore/Function.cpp Wed Apr 14 08:46:52 2004 @@ -228,6 +228,7 @@ case 'r': if (getName() == "llvm.returnaddress") return Intrinsic::returnaddress; if (getName() == "llvm.readport") return Intrinsic::readport; + if (getName() == "llvm.readio") return Intrinsic::readio; break; case 's': if (getName() == "llvm.setjmp") return Intrinsic::setjmp; @@ -240,6 +241,7 @@ if (getName() == "llvm.va_start") return Intrinsic::vastart; case 'w': if (getName() == "llvm.writeport") return Intrinsic::writeport; + if (getName() == "llvm.writeio") return Intrinsic::writeio; break; } // The "llvm." namespace is reserved! Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.92 llvm/lib/VMCore/Verifier.cpp:1.93 --- llvm/lib/VMCore/Verifier.cpp:1.92 Fri Apr 9 14:09:14 2004 +++ llvm/lib/VMCore/Verifier.cpp Wed Apr 14 08:46:52 2004 @@ -618,11 +618,33 @@ NumArgs = 2; break; + case Intrinsic::writeio: + Assert1(FT->getNumParams() == 2, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getParamType(0)->isFirstClassType(), + "First argument not a first class type!", IF); + Assert1(FT->getParamType(1)->getPrimitiveID() == Type::PointerTyID, + "Second argument not a pointer!", IF); + NumArgs = 2; + break; + case Intrinsic::readport: Assert1(FT->getNumParams() == 1, "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType()->isFirstClassType(), + "Return type is not a first class type!", IF); Assert1(FT->getParamType(0)->isUnsigned(), "First argument not unsigned int!", IF); + NumArgs = 1; + break; + + case Intrinsic:: readio: + Assert1(FT->getNumParams() == 1, + "Illegal # arguments for intrinsic function!", IF); + Assert1(FT->getReturnType()->isFirstClassType(), + "Return type is not a first class type!", IF); + Assert1(FT->getParamType(0)->getPrimitiveID() == Type::PointerTyID, + "First argument not a pointer!", IF); NumArgs = 1; break; From criswell at cs.uiuc.edu Wed Apr 14 08:54:02 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Wed Apr 14 08:54:02 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/io.llx Message-ID: <200404141353.IAA28834@choi.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: io.llx added (r1.1) --- Log message: Test for memory mapped I/O intrinsics. --- Diffs of the changes: (+21 -0) Index: llvm/test/Regression/CodeGen/X86/io.llx diff -c /dev/null llvm/test/Regression/CodeGen/X86/io.llx:1.1 *** /dev/null Wed Apr 14 08:53:06 2004 --- llvm/test/Regression/CodeGen/X86/io.llx Wed Apr 14 08:52:56 2004 *************** *** 0 **** --- 1,21 ---- + ; RUN: llvm-as < %s | llc -march=x86 + + implementation + + declare int %llvm.readio (int *) + declare void %llvm.writeio (int, int *) + + int %in(int * %p1) { + %p2 = alloca int + %i1 = call int %llvm.readio (int* %p1) + %i2 = call int %llvm.readio (int* %p2) + %r = add int %i1, %i2 + ret int %r + } + + + void %out(int* %p) { + call void(int, int*)* %llvm.writeio (int 1, int * %p) + ret void + } + From criswell at cs.uiuc.edu Wed Apr 14 09:51:02 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Wed Apr 14 09:51:02 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Verifier.cpp Message-ID: <200404141449.JAA06732@choi.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Verifier.cpp updated: 1.93 -> 1.94 --- Log message: Added code to verify that llvm.readio's pointer argument returns something that matches its return type. --- Diffs of the changes: (+8 -3) Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.93 llvm/lib/VMCore/Verifier.cpp:1.94 --- llvm/lib/VMCore/Verifier.cpp:1.93 Wed Apr 14 08:46:52 2004 +++ llvm/lib/VMCore/Verifier.cpp Wed Apr 14 09:49:36 2004 @@ -638,15 +638,20 @@ NumArgs = 1; break; - case Intrinsic:: readio: + case Intrinsic:: readio: { + const Type * ParamType = FT->getParamType(0); + const Type * ReturnType = FT->getReturnType(); + Assert1(FT->getNumParams() == 1, "Illegal # arguments for intrinsic function!", IF); - Assert1(FT->getReturnType()->isFirstClassType(), + Assert1(ReturnType->isFirstClassType(), "Return type is not a first class type!", IF); - Assert1(FT->getParamType(0)->getPrimitiveID() == Type::PointerTyID, + Assert1(ParamType->getPrimitiveID() == Type::PointerTyID, "First argument not a pointer!", IF); + Assert1(((dyn_cast(ParamType)->getContainedType(0)) == ReturnType), "Pointer type doesn't match return type!", IF); NumArgs = 1; break; + } case Intrinsic::setjmp: NumArgs = 1; break; case Intrinsic::longjmp: NumArgs = 2; break; From criswell at cs.uiuc.edu Wed Apr 14 10:08:01 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Wed Apr 14 10:08:01 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Verifier.cpp Message-ID: <200404141507.KAA08748@choi.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Verifier.cpp updated: 1.94 -> 1.95 --- Log message: Remove the return type check for llvm.readio. This check is done for all functions and is not needed here. Simplify the pointer type check per Chris's suggestions. --- Diffs of the changes: (+3 -4) Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.94 llvm/lib/VMCore/Verifier.cpp:1.95 --- llvm/lib/VMCore/Verifier.cpp:1.94 Wed Apr 14 09:49:36 2004 +++ llvm/lib/VMCore/Verifier.cpp Wed Apr 14 10:06:48 2004 @@ -644,11 +644,10 @@ Assert1(FT->getNumParams() == 1, "Illegal # arguments for intrinsic function!", IF); - Assert1(ReturnType->isFirstClassType(), - "Return type is not a first class type!", IF); - Assert1(ParamType->getPrimitiveID() == Type::PointerTyID, + Assert1(isa(ParamType), "First argument not a pointer!", IF); - Assert1(((dyn_cast(ParamType)->getContainedType(0)) == ReturnType), "Pointer type doesn't match return type!", IF); + Assert1(((cast(ParamType)->getElementType()) == ReturnType), + "Pointer type doesn't match return type!", IF); NumArgs = 1; break; } From lattner at cs.uiuc.edu Wed Apr 14 11:32:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Apr 14 11:32:01 2004 Subject: [llvm-commits] CVS: llvm/configure Message-ID: <200404141632.LAA02277@zion.cs.uiuc.edu> Changes in directory llvm: configure updated: 1.86 -> 1.87 --- Log message: Regenerated --- Diffs of the changes: (+11 -11) Index: llvm/configure diff -u llvm/configure:1.86 llvm/configure:1.87 --- llvm/configure:1.86 Tue Apr 13 14:03:49 2004 +++ llvm/configure Wed Apr 14 11:32:09 2004 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.57 for [LLVM] [1.1]. +# Generated by GNU Autoconf 2.57 for [LLVM] [1.3]. # # Report bugs to . # @@ -422,8 +422,8 @@ # Identity of this package. PACKAGE_NAME='[LLVM]' PACKAGE_TARNAME='--llvm--' -PACKAGE_VERSION='[1.1]' -PACKAGE_STRING='[LLVM] [1.1]' +PACKAGE_VERSION='[1.3]' +PACKAGE_STRING='[LLVM] [1.3]' PACKAGE_BUGREPORT='llvmbugs at cs.uiuc.edu' ac_subdirs_all="$ac_subdirs_all projects/${i}" @@ -954,7 +954,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures [LLVM] [1.1] to adapt to many kinds of systems. +\`configure' configures [LLVM] [1.3] to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1016,7 +1016,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of [LLVM] [1.1]:";; + short | recursive ) echo "Configuration of [LLVM] [1.3]:";; esac cat <<\_ACEOF @@ -1131,7 +1131,7 @@ test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -[LLVM] configure [1.1] +[LLVM] configure [1.3] generated by GNU Autoconf 2.57 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 @@ -1146,7 +1146,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by [LLVM] $as_me [1.1], which was +It was created by [LLVM] $as_me [1.3], which was generated by GNU Autoconf 2.57. Invocation command line was $ $0 $@ @@ -21907,7 +21907,7 @@ echo "$as_me:$LINENO: checking for POV-Ray benchmark sources" >&5 echo $ECHO_N "checking for POV-Ray benchmark sources... $ECHO_C" >&6 case "$povray" in -yes) +auto|yes) defaultdir=/home/vadve/shared/benchmarks/povray31 if test -d $defaultdir then @@ -21920,7 +21920,7 @@ povray=no fi ;; -auto|no) +no) USE_POVRAY= @@ -22450,7 +22450,7 @@ } >&5 cat >&5 <<_CSEOF -This file was extended by [LLVM] $as_me [1.1], which was +This file was extended by [LLVM] $as_me [1.3], which was generated by GNU Autoconf 2.57. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -22513,7 +22513,7 @@ cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -[LLVM] config.status [1.1] +[LLVM] config.status [1.3] configured by $0, generated by GNU Autoconf 2.57, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" From lattner at cs.uiuc.edu Wed Apr 14 11:33:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Apr 14 11:33:00 2004 Subject: [llvm-commits] CVS: llvm/autoconf/configure.ac Message-ID: <200404141632.LAA02290@zion.cs.uiuc.edu> Changes in directory llvm/autoconf: configure.ac updated: 1.84 -> 1.85 --- Log message: We are now on LLVM 1.3 Make autoconf default to checking to look to see if our funny directory exists --- Diffs of the changes: (+3 -3) Index: llvm/autoconf/configure.ac diff -u llvm/autoconf/configure.ac:1.84 llvm/autoconf/configure.ac:1.85 --- llvm/autoconf/configure.ac:1.84 Tue Apr 13 14:02:51 2004 +++ llvm/autoconf/configure.ac Wed Apr 14 11:32:34 2004 @@ -1,5 +1,5 @@ dnl Initialize autoconf -AC_INIT([[[LLVM]]],[[[1.1]]],[llvmbugs at cs.uiuc.edu]) +AC_INIT([[[LLVM]]],[[[1.3]]],[llvmbugs at cs.uiuc.edu]) dnl Place all of the extra autoconf files into the config subdirectory AC_CONFIG_AUX_DIR([autoconf]) @@ -350,7 +350,7 @@ povray=auto) AC_MSG_CHECKING([for POV-Ray benchmark sources]) case "$povray" in -yes) +auto|yes) defaultdir=/home/vadve/shared/benchmarks/povray31 if test -d $defaultdir then @@ -361,7 +361,7 @@ povray=no fi ;; -auto|no) +no) AC_SUBST(POVRAY_ROOT,[]) AC_SUBST(USE_POVRAY,[[]]) povray=no From alkis at cs.uiuc.edu Wed Apr 14 11:37:01 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed Apr 14 11:37:01 2004 Subject: [llvm-commits] CVS: llvm/projects/Java/ Message-ID: <200404141636.LAA02720@zion.cs.uiuc.edu> Changes in directory llvm/projects/Java: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/projects/Java added to the repository --- Diffs of the changes: (+0 -0) From alkis at cs.uiuc.edu Wed Apr 14 11:38:02 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed Apr 14 11:38:02 2004 Subject: [llvm-commits] CVS: llvm/projects/Java/lib/ Message-ID: <200404141637.LAA02919@zion.cs.uiuc.edu> Changes in directory llvm/projects/Java/lib: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/projects/Java/lib added to the repository --- Diffs of the changes: (+0 -0) From alkis at cs.uiuc.edu Wed Apr 14 11:38:09 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed Apr 14 11:38:09 2004 Subject: [llvm-commits] CVS: llvm/projects/Java/autoconf/ Message-ID: <200404141637.LAA02914@zion.cs.uiuc.edu> Changes in directory llvm/projects/Java/autoconf: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/projects/Java/autoconf added to the repository --- Diffs of the changes: (+0 -0) From alkis at cs.uiuc.edu Wed Apr 14 11:38:15 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed Apr 14 11:38:15 2004 Subject: [llvm-commits] CVS: llvm/projects/Java/tools/ Message-ID: <200404141637.LAA02924@zion.cs.uiuc.edu> Changes in directory llvm/projects/Java/tools: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/projects/Java/tools added to the repository --- Diffs of the changes: (+0 -0) From alkis at cs.uiuc.edu Wed Apr 14 11:39:01 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed Apr 14 11:39:01 2004 Subject: [llvm-commits] CVS: llvm/projects/Java/lib/ClassFile/ Message-ID: <200404141638.LAA02948@zion.cs.uiuc.edu> Changes in directory llvm/projects/Java/lib/ClassFile: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/projects/Java/lib/ClassFile added to the repository --- Diffs of the changes: (+0 -0) From alkis at cs.uiuc.edu Wed Apr 14 11:40:10 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed Apr 14 11:40:10 2004 Subject: [llvm-commits] CVS: llvm/projects/Java/tools/classdump/ Message-ID: <200404141639.LAA03109@zion.cs.uiuc.edu> Changes in directory llvm/projects/Java/tools/classdump: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/projects/Java/tools/classdump added to the repository --- Diffs of the changes: (+0 -0) From alkis at cs.uiuc.edu Wed Apr 14 11:41:02 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed Apr 14 11:41:02 2004 Subject: [llvm-commits] CVS: llvm/projects/Java/docs/ Message-ID: <200404141640.LAA03315@zion.cs.uiuc.edu> Changes in directory llvm/projects/Java/docs: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/projects/Java/docs added to the repository --- Diffs of the changes: (+0 -0) From gaeke at cs.uiuc.edu Wed Apr 14 12:19:02 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Apr 14 12:19:02 2004 Subject: [llvm-commits] CVS: reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp TraceOptEmitter.cpp Message-ID: <200404141718.MAA09748@zion.cs.uiuc.edu> Changes in directory reopt/lib/LightWtProfiling: RuntimeOptimizations.cpp updated: 1.25 -> 1.26 TraceOptEmitter.cpp updated: 1.2 -> 1.3 --- Log message: Make sure that a TargetData is added to the PassManager, and that createTraceOptEmitter ends up in the llvm namespace --- Diffs of the changes: (+9 -3) Index: reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp diff -u reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.25 reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.26 --- reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp:1.25 Tue Apr 13 16:29:43 2004 +++ reopt/lib/LightWtProfiling/RuntimeOptimizations.cpp Wed Apr 14 12:18:42 2004 @@ -34,6 +34,7 @@ static TargetMachine *Target = 0; static IntrinsicLowering *IL = 0; +static MachineCodeEmitter *MCE = 0; extern bool SaveStateToModule; extern bool SaveRegAllocState; @@ -56,6 +57,8 @@ if (!MP) initModules (); if (!IL) IL = new DefaultIntrinsicLowering (); if (!Target) Target = allocateSparcV9TargetMachine (*MP->getModule (), IL); + const TargetData &TD = Target->getTargetData (); + if (!MCE) MCE = createTraceOptEmitter (TD); // Turn the vector of basic blocks into a Trace, and then turn the Trace into // a TraceFunction. @@ -76,14 +79,13 @@ DEBUG(PM.add (new PrintFunctionPass ("Function created from trace for " + T.getFunction ()->getName () + ":\n", &std::cerr))); + PM.add (new TargetData (TD)); PM.add (createVerifierPass ()); Target->getJITInfo ()->addPassesToJITCompile (PM); DEBUG(PM.add (createMachineFunctionPrinterPass (&std::cerr, "Before unpacking:\n"))); PM.add (createUnpackTraceFunctionPass (Target, TF)); DEBUG(PM.add (createMachineFunctionPrinterPass (&std::cerr, "After unpacking:\n"))); Target->getJITInfo ()->addPassesToJITCompile (PM); - const TargetData &TD = Target->getTargetData (); - MachineCodeEmitter *MCE = createTraceOptEmitter (TD); Target->addPassesToEmitMachineCode (PM, *MCE); PM.run (*TF->TraceFn); Index: reopt/lib/LightWtProfiling/TraceOptEmitter.cpp diff -u reopt/lib/LightWtProfiling/TraceOptEmitter.cpp:1.2 reopt/lib/LightWtProfiling/TraceOptEmitter.cpp:1.3 --- reopt/lib/LightWtProfiling/TraceOptEmitter.cpp:1.2 Tue Apr 13 16:29:44 2004 +++ reopt/lib/LightWtProfiling/TraceOptEmitter.cpp Wed Apr 14 12:18:42 2004 @@ -80,11 +80,15 @@ // virtual uint64_t forceCompilationOf(Function *F); }; -} +} // end anonymous namespace + +namespace llvm { MachineCodeEmitter *createTraceOptEmitter(const TargetData &TD) { return new TraceOptEmitter(TD); } + +} // end namespace llvm void TraceOptEmitter::startFunction(MachineFunction &F) { // Round up to a 64-bit word boundary. From gaeke at cs.uiuc.edu Wed Apr 14 12:47:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Apr 14 12:47:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetData.h Message-ID: <200404141746.MAA13462@seraph.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetData.h updated: 1.23 -> 1.24 --- Log message: Add a copy constructor for TargetData. --- Diffs of the changes: (+16 -0) Index: llvm/include/llvm/Target/TargetData.h diff -u llvm/include/llvm/Target/TargetData.h:1.23 llvm/include/llvm/Target/TargetData.h:1.24 --- llvm/include/llvm/Target/TargetData.h:1.23 Thu Feb 26 02:01:57 2004 +++ llvm/include/llvm/Target/TargetData.h Wed Apr 14 12:45:48 2004 @@ -42,6 +42,7 @@ unsigned char DoubleAlignment; // Defaults to 8 bytes unsigned char PointerSize; // Defaults to 8 bytes unsigned char PointerAlignment; // Defaults to 8 bytes + public: TargetData(const std::string &TargetName = "", bool LittleEndian = false, @@ -50,6 +51,21 @@ unsigned char FloatAl = 4, unsigned char LongAl = 8, unsigned char IntAl = 4, unsigned char ShortAl = 2, unsigned char ByteAl = 1); + + // Copy constructor + TargetData (const TargetData &TD) : + ImmutablePass (), + LittleEndian (TD.isLittleEndian ()), + ByteAlignment (TD.getByteAlignment ()), + ShortAlignment (TD.getShortAlignment ()), + IntAlignment (TD.getIntAlignment ()), + LongAlignment (TD.getLongAlignment ()), + FloatAlignment (TD.getFloatAlignment ()), + DoubleAlignment (TD.getDoubleAlignment ()), + PointerSize (TD.getPointerSize ()), + PointerAlignment (TD.getPointerAlignment ()) { + } + TargetData(const std::string &ToolName, const Module *M); ~TargetData(); // Not virtual, do not subclass this class From gaeke at cs.uiuc.edu Wed Apr 14 12:47:08 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Apr 14 12:47:08 2004 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/JIT.cpp Message-ID: <200404141746.MAA13469@seraph.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: JIT.cpp updated: 1.32 -> 1.33 --- Log message: Add a TargetData to the PassManager regardless of the TargetMachine. This should unbreak the Sparc JIT again. --- Diffs of the changes: (+3 -0) Index: llvm/lib/ExecutionEngine/JIT/JIT.cpp diff -u llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.32 llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.33 --- llvm/lib/ExecutionEngine/JIT/JIT.cpp:1.32 Sat Jan 31 18:32:35 2004 +++ llvm/lib/ExecutionEngine/JIT/JIT.cpp Wed Apr 14 12:45:52 2004 @@ -32,6 +32,9 @@ // Initialize MCE MCE = createEmitter(*this); + // Add target data + PM.add (new TargetData (TM.getTargetData ())); + // Compile LLVM Code down to machine code in the intermediate representation TJI.addPassesToJITCompile(PM); From lattner at cs.uiuc.edu Wed Apr 14 16:12:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Apr 14 16:12:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ScalarEvolution.cpp Message-ID: <200404142111.QAA17008@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ScalarEvolution.cpp updated: 1.7 -> 1.8 --- Log message: This is a trivial tweak to the addrec insertion code: insert the increment at the bottom of the loop instead of the top. This reduces the number of overlapping live ranges a lot, for example, eliminating a spill in an important loop in 183.equake with linear scan. I still need to make the exit comparison of the loop use the post-incremented version of this variable, but this is an easy first step. --- Diffs of the changes: (+11 -6) Index: llvm/lib/Analysis/ScalarEvolution.cpp diff -u llvm/lib/Analysis/ScalarEvolution.cpp:1.7 llvm/lib/Analysis/ScalarEvolution.cpp:1.8 --- llvm/lib/Analysis/ScalarEvolution.cpp:1.7 Wed Apr 7 11:16:11 2004 +++ llvm/lib/Analysis/ScalarEvolution.cpp Wed Apr 14 16:11:25 2004 @@ -1465,14 +1465,19 @@ PHINode *PN = new PHINode(Ty, "indvar", Header->begin()); PN->addIncoming(Constant::getNullValue(Ty), L->getLoopPreheader()); - // Insert a unit add instruction after the PHI nodes in the header block. - BasicBlock::iterator I = PN; - while (isa(I)) ++I; + pred_iterator HPI = pred_begin(Header); + assert(HPI != pred_end(Header) && "Loop with zero preds???"); + if (!getLoop()->contains(*HPI)) ++HPI; + assert(HPI != pred_end(Header) && getLoop()->contains(*HPI) && + "No backedge in loop?"); - Constant *One = Ty->isFloatingPoint() ?(Constant*)ConstantFP::get(Ty, 1.0) - :(Constant*)ConstantInt::get(Ty, 1); + // Insert a unit add instruction right before the terminator corresponding + // to the back-edge. + Constant *One = Ty->isFloatingPoint() ? (Constant*)ConstantFP::get(Ty, 1.0) + : (Constant*)ConstantInt::get(Ty, 1); Instruction *Add = BinaryOperator::create(Instruction::Add, PN, One, - "indvar.next", I); + "indvar.next", + (*HPI)->getTerminator()); pred_iterator PI = pred_begin(Header); if (*PI == L->getLoopPreheader()) From gaeke at cs.uiuc.edu Wed Apr 14 16:22:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Wed Apr 14 16:22:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetData.cpp Message-ID: <200404142122.QAA17348@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetData.cpp updated: 1.44 -> 1.45 --- Log message: Fix typo. --- Diffs of the changes: (+1 -1) Index: llvm/lib/Target/TargetData.cpp diff -u llvm/lib/Target/TargetData.cpp:1.44 llvm/lib/Target/TargetData.cpp:1.45 --- llvm/lib/Target/TargetData.cpp:1.44 Sun Apr 4 20:29:25 2004 +++ llvm/lib/Target/TargetData.cpp Wed Apr 14 16:21:56 2004 @@ -82,7 +82,7 @@ unsigned char ByteAl) { // If this assert triggers, a pass "required" TargetData information, but the - // top level tool did not provide once for it. We do not want to default + // top level tool did not provide one for it. We do not want to default // construct, or else we might end up using a bad endianness or pointer size! // assert(!TargetName.empty() && From criswell at cs.uiuc.edu Wed Apr 14 16:29:01 2004 From: criswell at cs.uiuc.edu (John Criswell) Date: Wed Apr 14 16:29:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Message-ID: <200404142128.QAA27385@choi.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: InstSelectSimple.cpp updated: 1.237 -> 1.238 --- Log message: Remove code to adjust the iterator for llvm.readio and llvm.writeio. The iterator is pointing at the next instruction which should not disappear when doing the load/store replacement. --- Diffs of the changes: (+0 -10) Index: llvm/lib/Target/X86/InstSelectSimple.cpp diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.237 llvm/lib/Target/X86/InstSelectSimple.cpp:1.238 --- llvm/lib/Target/X86/InstSelectSimple.cpp:1.237 Tue Apr 13 17:13:14 2004 +++ llvm/lib/Target/X86/InstSelectSimple.cpp Wed Apr 14 16:27:56 2004 @@ -1548,11 +1548,6 @@ LoadInst * LI = new LoadInst (CI->getOperand(1), "", true, CI); CI->replaceAllUsesWith (LI); BB->getInstList().erase (CI); - if (Before) { // Move iterator to instruction after call - I = Before; ++I; - } else { - I = BB->begin(); - } break; } case Intrinsic::writeio: { @@ -1563,11 +1558,6 @@ CI->getOperand(2), true, CI); CI->replaceAllUsesWith (LI); BB->getInstList().erase (CI); - if (Before) { // Move iterator to instruction after call - I = Before; ++I; - } else { - I = BB->begin(); - } break; } default: From lattner at cs.uiuc.edu Wed Apr 14 17:02:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Apr 14 17:02:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ScalarEvolution.cpp Message-ID: <200404142201.RAA26882@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ScalarEvolution.cpp updated: 1.8 -> 1.9 --- Log message: Implement a FIXME: if we're going to insert a cast, we might as well only insert it once! --- Diffs of the changes: (+15 -1) Index: llvm/lib/Analysis/ScalarEvolution.cpp diff -u llvm/lib/Analysis/ScalarEvolution.cpp:1.8 llvm/lib/Analysis/ScalarEvolution.cpp:1.9 --- llvm/lib/Analysis/ScalarEvolution.cpp:1.8 Wed Apr 14 16:11:25 2004 +++ llvm/lib/Analysis/ScalarEvolution.cpp Wed Apr 14 17:01:22 2004 @@ -2484,7 +2484,21 @@ if (Constant *C = dyn_cast(V)) return ConstantExpr::getCast(C, Ty); else if (Instruction *I = dyn_cast(V)) { - // FIXME: check to see if there is already a cast! + // Check to see if there is already a cast. If there is, use it. + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); + UI != E; ++UI) { + if ((*UI)->getType() == Ty) + if (CastInst *CI = dyn_cast(cast(*UI))) { + BasicBlock::iterator It = I; ++It; + if (It != BasicBlock::iterator(CI)) { + // Splice the cast immediately after the operand in question. + I->getParent()->getInstList().splice(It, + CI->getParent()->getInstList(), + CI); + } + return CI; + } + } BasicBlock::iterator IP = I; ++IP; if (InvokeInst *II = dyn_cast(I)) IP = II->getNormalDest()->begin(); From alkis at cs.uiuc.edu Wed Apr 14 22:02:01 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed Apr 14 22:02:01 2004 Subject: [llvm-commits] CVS: llvm/projects/Java/include/ Message-ID: <200404150302.WAA01303@zion.cs.uiuc.edu> Changes in directory llvm/projects/Java/include: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/projects/Java/include added to the repository --- Diffs of the changes: (+0 -0) From alkis at cs.uiuc.edu Wed Apr 14 22:03:01 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed Apr 14 22:03:01 2004 Subject: [llvm-commits] CVS: llvm/projects/Java/include/llvm/ Message-ID: <200404150302.WAA01319@zion.cs.uiuc.edu> Changes in directory llvm/projects/Java/include/llvm: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/projects/Java/include/llvm added to the repository --- Diffs of the changes: (+0 -0) From alkis at cs.uiuc.edu Wed Apr 14 22:03:07 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Wed Apr 14 22:03:07 2004 Subject: [llvm-commits] CVS: llvm/projects/Java/include/llvm/Java/ Message-ID: <200404150302.WAA01335@zion.cs.uiuc.edu> Changes in directory llvm/projects/Java/include/llvm/Java: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/projects/Java/include/llvm/Java added to the repository --- Diffs of the changes: (+0 -0) From lattner at cs.uiuc.edu Thu Apr 15 09:18:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Apr 15 09:18:00 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ScalarEvolution.cpp Message-ID: <200404151417.JAA16185@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ScalarEvolution.cpp updated: 1.9 -> 1.10 --- Log message: Unbreak the build --- Diffs of the changes: (+1 -0) Index: llvm/lib/Analysis/ScalarEvolution.cpp diff -u llvm/lib/Analysis/ScalarEvolution.cpp:1.9 llvm/lib/Analysis/ScalarEvolution.cpp:1.10 --- llvm/lib/Analysis/ScalarEvolution.cpp:1.9 Wed Apr 14 17:01:22 2004 +++ llvm/lib/Analysis/ScalarEvolution.cpp Thu Apr 15 09:17:43 2004 @@ -2490,6 +2490,7 @@ if ((*UI)->getType() == Ty) if (CastInst *CI = dyn_cast(cast(*UI))) { BasicBlock::iterator It = I; ++It; + while (isa(It)) ++It; if (It != BasicBlock::iterator(CI)) { // Splice the cast immediately after the operand in question. I->getParent()->getInstList().splice(It, From lattner at cs.uiuc.edu Thu Apr 15 10:07:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Apr 15 10:07:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h Message-ID: <200404151507.KAA22518@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: ScalarEvolutionExpressions.h added (r1.1) --- Log message: Publically export all of these classes from the ScalarEvolutions.cpp file --- Diffs of the changes: (+461 -0) Index: llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h diff -c /dev/null llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h:1.1 *** /dev/null Thu Apr 15 10:07:09 2004 --- llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h Thu Apr 15 10:06:59 2004 *************** *** 0 **** --- 1,461 ---- + //===- llvm/Analysis/ScalarEvolutionExpressions.h - SCEV Exprs --*- 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 file defines the classes used to represent and build scalar expressions. + // + //===----------------------------------------------------------------------===// + + #ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H + #define LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H + + #include "llvm/Analysis/ScalarEvolution.h" + + namespace llvm { + class ConstantInt; + class ConstantRange; + + enum SCEVTypes { + // These should be ordered in terms of increasing complexity to make the + // folders simpler. + scConstant, scTruncate, scZeroExtend, scAddExpr, scMulExpr, scUDivExpr, + scAddRecExpr, scUnknown, scCouldNotCompute + }; + + //===--------------------------------------------------------------------===// + /// SCEVConstant - This class represents a constant integer value. + /// + class SCEVConstant : public SCEV { + ConstantInt *V; + SCEVConstant(ConstantInt *v) : SCEV(scConstant), V(v) {} + + virtual ~SCEVConstant(); + public: + /// get method - This just gets and returns a new SCEVConstant object. + /// + static SCEVHandle get(ConstantInt *V); + + ConstantInt *getValue() const { return V; } + + /// getValueRange - Return the tightest constant bounds that this value is + /// known to have. This method is only valid on integer SCEV objects. + virtual ConstantRange getValueRange() const; + + virtual bool isLoopInvariant(const Loop *L) const { + return true; + } + + virtual bool hasComputableLoopEvolution(const Loop *L) const { + return false; // Not loop variant + } + + virtual const Type *getType() const; + + Value *expandCodeFor(ScalarEvolutionRewriter &SER, + Instruction *InsertPt) { + return (Value*)getValue(); + } + + virtual void print(std::ostream &OS) const; + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SCEVConstant *S) { return true; } + static inline bool classof(const SCEV *S) { + return S->getSCEVType() == scConstant; + } + }; + + //===--------------------------------------------------------------------===// + /// SCEVTruncateExpr - This class represents a truncation of an integer value + /// to a smaller integer value. + /// + class SCEVTruncateExpr : public SCEV { + SCEVHandle Op; + const Type *Ty; + SCEVTruncateExpr(const SCEVHandle &op, const Type *ty); + virtual ~SCEVTruncateExpr(); + public: + /// get method - This just gets and returns a new SCEVTruncate object + /// + static SCEVHandle get(const SCEVHandle &Op, const Type *Ty); + + const SCEVHandle &getOperand() const { return Op; } + virtual const Type *getType() const { return Ty; } + + virtual bool isLoopInvariant(const Loop *L) const { + return Op->isLoopInvariant(L); + } + + virtual bool hasComputableLoopEvolution(const Loop *L) const { + return Op->hasComputableLoopEvolution(L); + } + + /// getValueRange - Return the tightest constant bounds that this value is + /// known to have. This method is only valid on integer SCEV objects. + virtual ConstantRange getValueRange() const; + + Value *expandCodeFor(ScalarEvolutionRewriter &SER, + Instruction *InsertPt); + + virtual void print(std::ostream &OS) const; + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SCEVTruncateExpr *S) { return true; } + static inline bool classof(const SCEV *S) { + return S->getSCEVType() == scTruncate; + } + }; + + //===--------------------------------------------------------------------===// + /// SCEVZeroExtendExpr - This class represents a zero extension of a small + /// integer value to a larger integer value. + /// + class SCEVZeroExtendExpr : public SCEV { + SCEVHandle Op; + const Type *Ty; + SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty); + virtual ~SCEVZeroExtendExpr(); + public: + /// get method - This just gets and returns a new SCEVZeroExtend object + /// + static SCEVHandle get(const SCEVHandle &Op, const Type *Ty); + + const SCEVHandle &getOperand() const { return Op; } + virtual const Type *getType() const { return Ty; } + + virtual bool isLoopInvariant(const Loop *L) const { + return Op->isLoopInvariant(L); + } + + virtual bool hasComputableLoopEvolution(const Loop *L) const { + return Op->hasComputableLoopEvolution(L); + } + + /// getValueRange - Return the tightest constant bounds that this value is + /// known to have. This method is only valid on integer SCEV objects. + virtual ConstantRange getValueRange() const; + + Value *expandCodeFor(ScalarEvolutionRewriter &SER, + Instruction *InsertPt); + + virtual void print(std::ostream &OS) const; + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SCEVZeroExtendExpr *S) { return true; } + static inline bool classof(const SCEV *S) { + return S->getSCEVType() == scZeroExtend; + } + }; + + + //===--------------------------------------------------------------------===// + /// SCEVCommutativeExpr - This node is the base class for n'ary commutative + /// operators. + /// + class SCEVCommutativeExpr : public SCEV { + std::vector Operands; + + protected: + SCEVCommutativeExpr(enum SCEVTypes T, const std::vector &ops) + : SCEV(T) { + Operands.reserve(ops.size()); + Operands.insert(Operands.end(), ops.begin(), ops.end()); + } + ~SCEVCommutativeExpr(); + + public: + unsigned getNumOperands() const { return Operands.size(); } + const SCEVHandle &getOperand(unsigned i) const { + assert(i < Operands.size() && "Operand index out of range!"); + return Operands[i]; + } + + const std::vector &getOperands() const { return Operands; } + typedef std::vector::const_iterator op_iterator; + op_iterator op_begin() const { return Operands.begin(); } + op_iterator op_end() const { return Operands.end(); } + + + virtual bool isLoopInvariant(const Loop *L) const { + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + if (!getOperand(i)->isLoopInvariant(L)) return false; + return true; + } + + virtual bool hasComputableLoopEvolution(const Loop *L) const { + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + if (getOperand(i)->hasComputableLoopEvolution(L)) return true; + return false; + } + + virtual const char *getOperationStr() const = 0; + + virtual const Type *getType() const { return getOperand(0)->getType(); } + virtual void print(std::ostream &OS) const; + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SCEVCommutativeExpr *S) { return true; } + static inline bool classof(const SCEV *S) { + return S->getSCEVType() == scAddExpr || + S->getSCEVType() == scMulExpr; + } + }; + + + //===--------------------------------------------------------------------===// + /// SCEVAddExpr - This node represents an addition of some number of SCEVs. + /// + class SCEVAddExpr : public SCEVCommutativeExpr { + SCEVAddExpr(const std::vector &ops) + : SCEVCommutativeExpr(scAddExpr, ops) { + } + + public: + static SCEVHandle get(std::vector &Ops); + + static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS) { + std::vector Ops; + Ops.push_back(LHS); + Ops.push_back(RHS); + return get(Ops); + } + + static SCEVHandle get(const SCEVHandle &Op0, const SCEVHandle &Op1, + const SCEVHandle &Op2) { + std::vector Ops; + Ops.push_back(Op0); + Ops.push_back(Op1); + Ops.push_back(Op2); + return get(Ops); + } + + virtual const char *getOperationStr() const { return " + "; } + + Value *expandCodeFor(ScalarEvolutionRewriter &SER, + Instruction *InsertPt); + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SCEVAddExpr *S) { return true; } + static inline bool classof(const SCEV *S) { + return S->getSCEVType() == scAddExpr; + } + }; + + //===--------------------------------------------------------------------===// + /// SCEVMulExpr - This node represents multiplication of some number of SCEVs. + /// + class SCEVMulExpr : public SCEVCommutativeExpr { + SCEVMulExpr(const std::vector &ops) + : SCEVCommutativeExpr(scMulExpr, ops) { + } + + public: + static SCEVHandle get(std::vector &Ops); + + static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS) { + std::vector Ops; + Ops.push_back(LHS); + Ops.push_back(RHS); + return get(Ops); + } + + virtual const char *getOperationStr() const { return " * "; } + + Value *expandCodeFor(ScalarEvolutionRewriter &SER, + Instruction *InsertPt); + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SCEVMulExpr *S) { return true; } + static inline bool classof(const SCEV *S) { + return S->getSCEVType() == scMulExpr; + } + }; + + + //===--------------------------------------------------------------------===// + /// SCEVUDivExpr - This class represents a binary unsigned division operation. + /// + class SCEVUDivExpr : public SCEV { + SCEVHandle LHS, RHS; + SCEVUDivExpr(const SCEVHandle &lhs, const SCEVHandle &rhs) + : SCEV(scUDivExpr), LHS(lhs), RHS(rhs) {} + + virtual ~SCEVUDivExpr(); + public: + /// get method - This just gets and returns a new SCEVUDiv object. + /// + static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS); + + const SCEVHandle &getLHS() const { return LHS; } + const SCEVHandle &getRHS() const { return RHS; } + + virtual bool isLoopInvariant(const Loop *L) const { + return LHS->isLoopInvariant(L) && RHS->isLoopInvariant(L); + } + + virtual bool hasComputableLoopEvolution(const Loop *L) const { + return LHS->hasComputableLoopEvolution(L) && + RHS->hasComputableLoopEvolution(L); + } + + virtual const Type *getType() const; + + Value *expandCodeFor(ScalarEvolutionRewriter &SER, + Instruction *InsertPt); + + void print(std::ostream &OS) const; + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SCEVUDivExpr *S) { return true; } + static inline bool classof(const SCEV *S) { + return S->getSCEVType() == scUDivExpr; + } + }; + + + //===--------------------------------------------------------------------===// + /// SCEVAddRecExpr - This node represents a polynomial recurrence on the trip + /// count of the specified loop. + /// + /// All operands of an AddRec are required to be loop invariant. + /// + class SCEVAddRecExpr : public SCEV { + std::vector Operands; + const Loop *L; + + SCEVAddRecExpr(const std::vector &ops, const Loop *l) + : SCEV(scAddRecExpr), Operands(ops), L(l) { + for (unsigned i = 0, e = Operands.size(); i != e; ++i) + assert(Operands[i]->isLoopInvariant(l) && + "Operands of AddRec must be loop-invariant!"); + } + ~SCEVAddRecExpr(); + public: + static SCEVHandle get(const SCEVHandle &Start, const SCEVHandle &Step, + const Loop *); + static SCEVHandle get(std::vector &Operands, + const Loop *); + static SCEVHandle get(const std::vector &Operands, + const Loop *L) { + std::vector NewOp(Operands); + return get(NewOp, L); + } + + typedef std::vector::const_iterator op_iterator; + op_iterator op_begin() const { return Operands.begin(); } + op_iterator op_end() const { return Operands.end(); } + + unsigned getNumOperands() const { return Operands.size(); } + const SCEVHandle &getOperand(unsigned i) const { return Operands[i]; } + const SCEVHandle &getStart() const { return Operands[0]; } + const Loop *getLoop() const { return L; } + + + /// getStepRecurrence - This method constructs and returns the recurrence + /// indicating how much this expression steps by. If this is a polynomial + /// of degree N, it returns a chrec of degree N-1. + SCEVHandle getStepRecurrence() const { + if (getNumOperands() == 2) return getOperand(1); + return SCEVAddRecExpr::get(std::vector(op_begin()+1,op_end()), + getLoop()); + } + + virtual bool hasComputableLoopEvolution(const Loop *QL) const { + if (L == QL) return true; + /// FIXME: What if the start or step value a recurrence for the specified + /// loop? + return false; + } + + virtual bool isLoopInvariant(const Loop *QueryLoop) const; + + virtual const Type *getType() const { return Operands[0]->getType(); } + + Value *expandCodeFor(ScalarEvolutionRewriter &SER, + Instruction *InsertPt); + + + /// isAffine - Return true if this is an affine AddRec (i.e., it represents + /// an expressions A+B*x where A and B are loop invariant values. + bool isAffine() const { + // We know that the start value is invariant. This expression is thus + // affine iff the step is also invariant. + return getNumOperands() == 2; + } + + /// isQuadratic - Return true if this is an quadratic AddRec (i.e., it + /// represents an expressions A+B*x+C*x^2 where A, B and C are loop + /// invariant values. This corresponds to an addrec of the form {L,+,M,+,N} + bool isQuadratic() const { + return getNumOperands() == 3; + } + + /// evaluateAtIteration - Return the value of this chain of recurrences at + /// the specified iteration number. + SCEVHandle evaluateAtIteration(SCEVHandle It) const; + + /// getNumIterationsInRange - Return the number of iterations of this loop + /// that produce values in the specified constant range. Another way of + /// looking at this is that it returns the first iteration number where the + /// value is not in the condition, thus computing the exit count. If the + /// iteration count can't be computed, an instance of SCEVCouldNotCompute is + /// returned. + SCEVHandle getNumIterationsInRange(ConstantRange Range) const; + + + virtual void print(std::ostream &OS) const; + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SCEVAddRecExpr *S) { return true; } + static inline bool classof(const SCEV *S) { + return S->getSCEVType() == scAddRecExpr; + } + }; + + //===--------------------------------------------------------------------===// + /// SCEVUnknown - This means that we are dealing with an entirely unknown SCEV + /// value, and only represent it as it's LLVM Value. This is the "bottom" + /// value for the analysis. + /// + class SCEVUnknown : public SCEV { + Value *V; + SCEVUnknown(Value *v) : SCEV(scUnknown), V(v) {} + + protected: + ~SCEVUnknown(); + public: + /// get method - For SCEVUnknown, this just gets and returns a new + /// SCEVUnknown. + static SCEVHandle get(Value *V); + + Value *getValue() const { return V; } + + Value *expandCodeFor(ScalarEvolutionRewriter &SER, + Instruction *InsertPt) { + return V; + } + + virtual bool isLoopInvariant(const Loop *L) const; + virtual bool hasComputableLoopEvolution(const Loop *QL) const { + return false; // not computable + } + + virtual const Type *getType() const; + + virtual void print(std::ostream &OS) const; + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SCEVUnknown *S) { return true; } + static inline bool classof(const SCEV *S) { + return S->getSCEVType() == scUnknown; + } + }; + } + + #endif + From lattner at cs.uiuc.edu Thu Apr 15 10:08:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Apr 15 10:08:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ScalarEvolution.cpp Message-ID: <200404151507.KAA22595@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ScalarEvolution.cpp updated: 1.10 -> 1.11 --- Log message: Factor a bunch of classes out into a public header --- Diffs of the changes: (+142 -553) Index: llvm/lib/Analysis/ScalarEvolution.cpp diff -u llvm/lib/Analysis/ScalarEvolution.cpp:1.10 llvm/lib/Analysis/ScalarEvolution.cpp:1.11 --- llvm/lib/Analysis/ScalarEvolution.cpp:1.10 Thu Apr 15 09:17:43 2004 +++ llvm/lib/Analysis/ScalarEvolution.cpp Thu Apr 15 10:07:24 2004 @@ -63,7 +63,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" @@ -101,13 +101,6 @@ // Implementation of the SCEV class. // namespace { - enum SCEVTypes { - // These should be ordered in terms of increasing complexity to make the - // folders simpler. - scConstant, scTruncate, scZeroExtend, scAddExpr, scMulExpr, scUDivExpr, - scAddRecExpr, scUnknown, scCouldNotCompute - }; - /// SCEVComplexityCompare - Return true if the complexity of the LHS is less /// than the complexity of the RHS. If the SCEVs have identical complexity, /// order them by their addresses. This comparator is used to canonicalize @@ -172,593 +165,181 @@ } -//===----------------------------------------------------------------------===// -// SCEVConstant - This class represents a constant integer value. -// -namespace { - class SCEVConstant; - // SCEVConstants - Only allow the creation of one SCEVConstant for any - // particular value. Don't use a SCEVHandle here, or else the object will - // never be deleted! - std::map SCEVConstants; - - class SCEVConstant : public SCEV { - ConstantInt *V; - SCEVConstant(ConstantInt *v) : SCEV(scConstant), V(v) {} - - virtual ~SCEVConstant() { - SCEVConstants.erase(V); - } - public: - /// get method - This just gets and returns a new SCEVConstant object. - /// - static SCEVHandle get(ConstantInt *V) { - // Make sure that SCEVConstant instances are all unsigned. - if (V->getType()->isSigned()) { - const Type *NewTy = V->getType()->getUnsignedVersion(); - V = cast(ConstantExpr::getCast(V, NewTy)); - } - - SCEVConstant *&R = SCEVConstants[V]; - if (R == 0) R = new SCEVConstant(V); - return R; - } - - ConstantInt *getValue() const { return V; } - - /// getValueRange - Return the tightest constant bounds that this value is - /// known to have. This method is only valid on integer SCEV objects. - virtual ConstantRange getValueRange() const { - return ConstantRange(V); - } - - virtual bool isLoopInvariant(const Loop *L) const { - return true; - } - - virtual bool hasComputableLoopEvolution(const Loop *L) const { - return false; // Not loop variant - } - - virtual const Type *getType() const { return V->getType(); } - - Value *expandCodeFor(ScalarEvolutionRewriter &SER, - Instruction *InsertPt) { - return getValue(); - } - - virtual void print(std::ostream &OS) const { - WriteAsOperand(OS, V, false); - } +// SCEVConstants - Only allow the creation of one SCEVConstant for any +// particular value. Don't use a SCEVHandle here, or else the object will +// never be deleted! +static std::map SCEVConstants; + - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVConstant *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scConstant; - } - }; +SCEVConstant::~SCEVConstant() { + SCEVConstants.erase(V); } - -//===----------------------------------------------------------------------===// -// SCEVTruncateExpr - This class represents a truncation of an integer value to -// a smaller integer value. -// -namespace { - class SCEVTruncateExpr; - // SCEVTruncates - Only allow the creation of one SCEVTruncateExpr for any - // particular input. Don't use a SCEVHandle here, or else the object will - // never be deleted! - std::map, SCEVTruncateExpr*> SCEVTruncates; - - class SCEVTruncateExpr : public SCEV { - SCEVHandle Op; - const Type *Ty; - SCEVTruncateExpr(const SCEVHandle &op, const Type *ty) - : SCEV(scTruncate), Op(op), Ty(ty) { - assert(Op->getType()->isInteger() && Ty->isInteger() && - Ty->isUnsigned() && - "Cannot truncate non-integer value!"); - assert(Op->getType()->getPrimitiveSize() > Ty->getPrimitiveSize() && - "This is not a truncating conversion!"); - } - - virtual ~SCEVTruncateExpr() { - SCEVTruncates.erase(std::make_pair(Op, Ty)); - } - public: - /// get method - This just gets and returns a new SCEVTruncate object - /// - static SCEVHandle get(const SCEVHandle &Op, const Type *Ty); - - const SCEVHandle &getOperand() const { return Op; } - virtual const Type *getType() const { return Ty; } - - virtual bool isLoopInvariant(const Loop *L) const { - return Op->isLoopInvariant(L); - } - - virtual bool hasComputableLoopEvolution(const Loop *L) const { - return Op->hasComputableLoopEvolution(L); - } - - /// getValueRange - Return the tightest constant bounds that this value is - /// known to have. This method is only valid on integer SCEV objects. - virtual ConstantRange getValueRange() const { - return getOperand()->getValueRange().truncate(getType()); - } - - Value *expandCodeFor(ScalarEvolutionRewriter &SER, - Instruction *InsertPt); - - virtual void print(std::ostream &OS) const { - OS << "(truncate " << *Op << " to " << *Ty << ")"; - } - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVTruncateExpr *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scTruncate; - } - }; +SCEVHandle SCEVConstant::get(ConstantInt *V) { + // Make sure that SCEVConstant instances are all unsigned. + if (V->getType()->isSigned()) { + const Type *NewTy = V->getType()->getUnsignedVersion(); + V = cast(ConstantExpr::getCast(V, NewTy)); + } + + SCEVConstant *&R = SCEVConstants[V]; + if (R == 0) R = new SCEVConstant(V); + return R; } - -//===----------------------------------------------------------------------===// -// SCEVZeroExtendExpr - This class represents a zero extension of a small -// integer value to a larger integer value. -// -namespace { - class SCEVZeroExtendExpr; - // SCEVZeroExtends - Only allow the creation of one SCEVZeroExtendExpr for any - // particular input. Don't use a SCEVHandle here, or else the object will - // never be deleted! - std::map, SCEVZeroExtendExpr*> SCEVZeroExtends; - - class SCEVZeroExtendExpr : public SCEV { - SCEVHandle Op; - const Type *Ty; - SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty) - : SCEV(scTruncate), Op(Op), Ty(ty) { - assert(Op->getType()->isInteger() && Ty->isInteger() && - Ty->isUnsigned() && - "Cannot zero extend non-integer value!"); - assert(Op->getType()->getPrimitiveSize() < Ty->getPrimitiveSize() && - "This is not an extending conversion!"); - } - - virtual ~SCEVZeroExtendExpr() { - SCEVZeroExtends.erase(std::make_pair(Op, Ty)); - } - public: - /// get method - This just gets and returns a new SCEVZeroExtend object - /// - static SCEVHandle get(const SCEVHandle &Op, const Type *Ty); - - const SCEVHandle &getOperand() const { return Op; } - virtual const Type *getType() const { return Ty; } - - virtual bool isLoopInvariant(const Loop *L) const { - return Op->isLoopInvariant(L); - } - - virtual bool hasComputableLoopEvolution(const Loop *L) const { - return Op->hasComputableLoopEvolution(L); - } - - /// getValueRange - Return the tightest constant bounds that this value is - /// known to have. This method is only valid on integer SCEV objects. - virtual ConstantRange getValueRange() const { - return getOperand()->getValueRange().zeroExtend(getType()); - } - - Value *expandCodeFor(ScalarEvolutionRewriter &SER, - Instruction *InsertPt); - - virtual void print(std::ostream &OS) const { - OS << "(zeroextend " << *Op << " to " << *Ty << ")"; - } - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVZeroExtendExpr *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scZeroExtend; - } - }; +ConstantRange SCEVConstant::getValueRange() const { + return ConstantRange(V); } +const Type *SCEVConstant::getType() const { return V->getType(); } -//===----------------------------------------------------------------------===// -// SCEVCommutativeExpr - This node is the base class for n'ary commutative -// operators. - -namespace { - class SCEVCommutativeExpr; - // SCEVCommExprs - Only allow the creation of one SCEVCommutativeExpr for any - // particular input. Don't use a SCEVHandle here, or else the object will - // never be deleted! - std::map >, - SCEVCommutativeExpr*> SCEVCommExprs; - - class SCEVCommutativeExpr : public SCEV { - std::vector Operands; - - protected: - SCEVCommutativeExpr(enum SCEVTypes T, const std::vector &ops) - : SCEV(T) { - Operands.reserve(ops.size()); - Operands.insert(Operands.end(), ops.begin(), ops.end()); - } - - ~SCEVCommutativeExpr() { - SCEVCommExprs.erase(std::make_pair(getSCEVType(), - std::vector(Operands.begin(), - Operands.end()))); - } - - public: - unsigned getNumOperands() const { return Operands.size(); } - const SCEVHandle &getOperand(unsigned i) const { - assert(i < Operands.size() && "Operand index out of range!"); - return Operands[i]; - } - - const std::vector &getOperands() const { return Operands; } - typedef std::vector::const_iterator op_iterator; - op_iterator op_begin() const { return Operands.begin(); } - op_iterator op_end() const { return Operands.end(); } - - - virtual bool isLoopInvariant(const Loop *L) const { - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (!getOperand(i)->isLoopInvariant(L)) return false; - return true; - } - - virtual bool hasComputableLoopEvolution(const Loop *L) const { - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (getOperand(i)->hasComputableLoopEvolution(L)) return true; - return false; - } - - virtual const Type *getType() const { return getOperand(0)->getType(); } - - virtual const char *getOperationStr() const = 0; - - virtual void print(std::ostream &OS) const { - assert(Operands.size() > 1 && "This plus expr shouldn't exist!"); - const char *OpStr = getOperationStr(); - OS << "(" << *Operands[0]; - for (unsigned i = 1, e = Operands.size(); i != e; ++i) - OS << OpStr << *Operands[i]; - OS << ")"; - } - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVCommutativeExpr *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scAddExpr || - S->getSCEVType() == scMulExpr; - } - }; +void SCEVConstant::print(std::ostream &OS) const { + WriteAsOperand(OS, V, false); } -//===----------------------------------------------------------------------===// -// SCEVAddExpr - This node represents an addition of some number of SCEV's. -// -namespace { - class SCEVAddExpr : public SCEVCommutativeExpr { - SCEVAddExpr(const std::vector &ops) - : SCEVCommutativeExpr(scAddExpr, ops) { - } - - public: - static SCEVHandle get(std::vector &Ops); - - static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS) { - std::vector Ops; - Ops.push_back(LHS); - Ops.push_back(RHS); - return get(Ops); - } +// SCEVTruncates - Only allow the creation of one SCEVTruncateExpr for any +// particular input. Don't use a SCEVHandle here, or else the object will +// never be deleted! +static std::map, SCEVTruncateExpr*> SCEVTruncates; - static SCEVHandle get(const SCEVHandle &Op0, const SCEVHandle &Op1, - const SCEVHandle &Op2) { - std::vector Ops; - Ops.push_back(Op0); - Ops.push_back(Op1); - Ops.push_back(Op2); - return get(Ops); - } - - virtual const char *getOperationStr() const { return " + "; } - - Value *expandCodeFor(ScalarEvolutionRewriter &SER, - Instruction *InsertPt); - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVAddExpr *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scAddExpr; - } - }; +SCEVTruncateExpr::SCEVTruncateExpr(const SCEVHandle &op, const Type *ty) + : SCEV(scTruncate), Op(op), Ty(ty) { + assert(Op->getType()->isInteger() && Ty->isInteger() && + Ty->isUnsigned() && + "Cannot truncate non-integer value!"); + assert(Op->getType()->getPrimitiveSize() > Ty->getPrimitiveSize() && + "This is not a truncating conversion!"); } -//===----------------------------------------------------------------------===// -// SCEVMulExpr - This node represents multiplication of some number of SCEV's. -// -namespace { - class SCEVMulExpr : public SCEVCommutativeExpr { - SCEVMulExpr(const std::vector &ops) - : SCEVCommutativeExpr(scMulExpr, ops) { - } - - public: - static SCEVHandle get(std::vector &Ops); - - static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS) { - std::vector Ops; - Ops.push_back(LHS); - Ops.push_back(RHS); - return get(Ops); - } - - virtual const char *getOperationStr() const { return " * "; } - - Value *expandCodeFor(ScalarEvolutionRewriter &SER, - Instruction *InsertPt); - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVMulExpr *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scMulExpr; - } - }; +SCEVTruncateExpr::~SCEVTruncateExpr() { + SCEVTruncates.erase(std::make_pair(Op, Ty)); } - -//===----------------------------------------------------------------------===// -// SCEVUDivExpr - This class represents a binary unsigned division operation. -// -namespace { - class SCEVUDivExpr; - // SCEVUDivs - Only allow the creation of one SCEVUDivExpr for any particular - // input. Don't use a SCEVHandle here, or else the object will never be - // deleted! - std::map, SCEVUDivExpr*> SCEVUDivs; - - class SCEVUDivExpr : public SCEV { - SCEVHandle LHS, RHS; - SCEVUDivExpr(const SCEVHandle &lhs, const SCEVHandle &rhs) - : SCEV(scUDivExpr), LHS(lhs), RHS(rhs) {} - - virtual ~SCEVUDivExpr() { - SCEVUDivs.erase(std::make_pair(LHS, RHS)); - } - public: - /// get method - This just gets and returns a new SCEVUDiv object. - /// - static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS); - - const SCEVHandle &getLHS() const { return LHS; } - const SCEVHandle &getRHS() const { return RHS; } - - virtual bool isLoopInvariant(const Loop *L) const { - return LHS->isLoopInvariant(L) && RHS->isLoopInvariant(L); - } - - virtual bool hasComputableLoopEvolution(const Loop *L) const { - return LHS->hasComputableLoopEvolution(L) && - RHS->hasComputableLoopEvolution(L); - } - - virtual const Type *getType() const { - const Type *Ty = LHS->getType(); - if (Ty->isSigned()) Ty = Ty->getUnsignedVersion(); - return Ty; - } - - Value *expandCodeFor(ScalarEvolutionRewriter &SER, - Instruction *InsertPt); - - virtual void print(std::ostream &OS) const { - OS << "(" << *LHS << " /u " << *RHS << ")"; - } - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVUDivExpr *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scUDivExpr; - } - }; +ConstantRange SCEVTruncateExpr::getValueRange() const { + return getOperand()->getValueRange().truncate(getType()); } +void SCEVTruncateExpr::print(std::ostream &OS) const { + OS << "(truncate " << *Op << " to " << *Ty << ")"; +} -//===----------------------------------------------------------------------===// +// SCEVZeroExtends - Only allow the creation of one SCEVZeroExtendExpr for any +// particular input. Don't use a SCEVHandle here, or else the object will never +// be deleted! +static std::map, + SCEVZeroExtendExpr*> SCEVZeroExtends; -// SCEVAddRecExpr - This node represents a polynomial recurrence on the trip -// count of the specified loop. -// -// All operands of an AddRec are required to be loop invariant. -// -namespace { - class SCEVAddRecExpr; - // SCEVAddRecExprs - Only allow the creation of one SCEVAddRecExpr for any - // particular input. Don't use a SCEVHandle here, or else the object will - // never be deleted! - std::map >, - SCEVAddRecExpr*> SCEVAddRecExprs; +SCEVZeroExtendExpr::SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty) + : SCEV(scTruncate), Op(Op), Ty(ty) { + assert(Op->getType()->isInteger() && Ty->isInteger() && + Ty->isUnsigned() && + "Cannot zero extend non-integer value!"); + assert(Op->getType()->getPrimitiveSize() < Ty->getPrimitiveSize() && + "This is not an extending conversion!"); +} - class SCEVAddRecExpr : public SCEV { - std::vector Operands; - const Loop *L; +SCEVZeroExtendExpr::~SCEVZeroExtendExpr() { + SCEVZeroExtends.erase(std::make_pair(Op, Ty)); +} - SCEVAddRecExpr(const std::vector &ops, const Loop *l) - : SCEV(scAddRecExpr), Operands(ops), L(l) { - for (unsigned i = 0, e = Operands.size(); i != e; ++i) - assert(Operands[i]->isLoopInvariant(l) && - "Operands of AddRec must be loop-invariant!"); - } - ~SCEVAddRecExpr() { - SCEVAddRecExprs.erase(std::make_pair(L, - std::vector(Operands.begin(), - Operands.end()))); - } - public: - static SCEVHandle get(const SCEVHandle &Start, const SCEVHandle &Step, - const Loop *); - static SCEVHandle get(std::vector &Operands, - const Loop *); - static SCEVHandle get(const std::vector &Operands, - const Loop *L) { - std::vector NewOp(Operands); - return get(NewOp, L); - } +ConstantRange SCEVZeroExtendExpr::getValueRange() const { + return getOperand()->getValueRange().zeroExtend(getType()); +} - typedef std::vector::const_iterator op_iterator; - op_iterator op_begin() const { return Operands.begin(); } - op_iterator op_end() const { return Operands.end(); } - - unsigned getNumOperands() const { return Operands.size(); } - const SCEVHandle &getOperand(unsigned i) const { return Operands[i]; } - const SCEVHandle &getStart() const { return Operands[0]; } - const Loop *getLoop() const { return L; } - - - /// getStepRecurrence - This method constructs and returns the recurrence - /// indicating how much this expression steps by. If this is a polynomial - /// of degree N, it returns a chrec of degree N-1. - SCEVHandle getStepRecurrence() const { - if (getNumOperands() == 2) return getOperand(1); - return SCEVAddRecExpr::get(std::vector(op_begin()+1,op_end()), - getLoop()); - } +void SCEVZeroExtendExpr::print(std::ostream &OS) const { + OS << "(zeroextend " << *Op << " to " << *Ty << ")"; +} - virtual bool hasComputableLoopEvolution(const Loop *QL) const { - if (L == QL) return true; - /// FIXME: What if the start or step value a recurrence for the specified - /// loop? - return false; - } +// SCEVCommExprs - Only allow the creation of one SCEVCommutativeExpr for any +// particular input. Don't use a SCEVHandle here, or else the object will never +// be deleted! +static std::map >, + SCEVCommutativeExpr*> SCEVCommExprs; +SCEVCommutativeExpr::~SCEVCommutativeExpr() { + SCEVCommExprs.erase(std::make_pair(getSCEVType(), + std::vector(Operands.begin(), + Operands.end()))); +} - virtual bool isLoopInvariant(const Loop *QueryLoop) const { - // This recurrence is invariant w.r.t to QueryLoop iff QueryLoop doesn't - // contain L. - return !QueryLoop->contains(L->getHeader()); - } +void SCEVCommutativeExpr::print(std::ostream &OS) const { + assert(Operands.size() > 1 && "This plus expr shouldn't exist!"); + const char *OpStr = getOperationStr(); + OS << "(" << *Operands[0]; + for (unsigned i = 1, e = Operands.size(); i != e; ++i) + OS << OpStr << *Operands[i]; + OS << ")"; +} - virtual const Type *getType() const { return Operands[0]->getType(); } +// SCEVUDivs - Only allow the creation of one SCEVUDivExpr for any particular +// input. Don't use a SCEVHandle here, or else the object will never be +// deleted! +static std::map, SCEVUDivExpr*> SCEVUDivs; - Value *expandCodeFor(ScalarEvolutionRewriter &SER, - Instruction *InsertPt); +SCEVUDivExpr::~SCEVUDivExpr() { + SCEVUDivs.erase(std::make_pair(LHS, RHS)); +} +void SCEVUDivExpr::print(std::ostream &OS) const { + OS << "(" << *LHS << " /u " << *RHS << ")"; +} - /// isAffine - Return true if this is an affine AddRec (i.e., it represents - /// an expressions A+B*x where A and B are loop invariant values. - bool isAffine() const { - // We know that the start value is invariant. This expression is thus - // affine iff the step is also invariant. - return getNumOperands() == 2; - } +const Type *SCEVUDivExpr::getType() const { + const Type *Ty = LHS->getType(); + if (Ty->isSigned()) Ty = Ty->getUnsignedVersion(); + return Ty; +} - /// isQuadratic - Return true if this is an quadratic AddRec (i.e., it - /// represents an expressions A+B*x+C*x^2 where A, B and C are loop - /// invariant values. This corresponds to an addrec of the form {L,+,M,+,N} - bool isQuadratic() const { - return getNumOperands() == 3; - } +// SCEVAddRecExprs - Only allow the creation of one SCEVAddRecExpr for any +// particular input. Don't use a SCEVHandle here, or else the object will never +// be deleted! +static std::map >, + SCEVAddRecExpr*> SCEVAddRecExprs; - /// evaluateAtIteration - Return the value of this chain of recurrences at - /// the specified iteration number. - SCEVHandle evaluateAtIteration(SCEVHandle It) const; - - /// getNumIterationsInRange - Return the number of iterations of this loop - /// that produce values in the specified constant range. Another way of - /// looking at this is that it returns the first iteration number where the - /// value is not in the condition, thus computing the exit count. If the - /// iteration count can't be computed, an instance of SCEVCouldNotCompute is - /// returned. - SCEVHandle getNumIterationsInRange(ConstantRange Range) const; - - - virtual void print(std::ostream &OS) const { - OS << "{" << *Operands[0]; - for (unsigned i = 1, e = Operands.size(); i != e; ++i) - OS << ",+," << *Operands[i]; - OS << "}<" << L->getHeader()->getName() + ">"; - } +SCEVAddRecExpr::~SCEVAddRecExpr() { + SCEVAddRecExprs.erase(std::make_pair(L, + std::vector(Operands.begin(), + Operands.end()))); +} - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVAddRecExpr *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scAddRecExpr; - } - }; +bool SCEVAddRecExpr::isLoopInvariant(const Loop *QueryLoop) const { + // This recurrence is invariant w.r.t to QueryLoop iff QueryLoop doesn't + // contain L. + return !QueryLoop->contains(L->getHeader()); } -//===----------------------------------------------------------------------===// -// SCEVUnknown - This means that we are dealing with an entirely unknown SCEV -// value, and only represent it as it's LLVM Value. This is the "bottom" value -// for the analysis. -// -namespace { - class SCEVUnknown; - // SCEVUnknowns - Only allow the creation of one SCEVUnknown for any - // particular value. Don't use a SCEVHandle here, or else the object will - // never be deleted! - std::map SCEVUnknowns; - - class SCEVUnknown : public SCEV { - Value *V; - SCEVUnknown(Value *v) : SCEV(scUnknown), V(v) {} - - protected: - ~SCEVUnknown() { SCEVUnknowns.erase(V); } - public: - /// get method - For SCEVUnknown, this just gets and returns a new - /// SCEVUnknown. - static SCEVHandle get(Value *V) { - if (ConstantInt *CI = dyn_cast(V)) - return SCEVConstant::get(CI); - SCEVUnknown *&Result = SCEVUnknowns[V]; - if (Result == 0) Result = new SCEVUnknown(V); - return Result; - } +void SCEVAddRecExpr::print(std::ostream &OS) const { + OS << "{" << *Operands[0]; + for (unsigned i = 1, e = Operands.size(); i != e; ++i) + OS << ",+," << *Operands[i]; + OS << "}<" << L->getHeader()->getName() + ">"; +} - Value *getValue() const { return V; } +// SCEVUnknowns - Only allow the creation of one SCEVUnknown for any particular +// value. Don't use a SCEVHandle here, or else the object will never be +// deleted! +static std::map SCEVUnknowns; - Value *expandCodeFor(ScalarEvolutionRewriter &SER, - Instruction *InsertPt) { - return V; - } +SCEVUnknown::~SCEVUnknown() { SCEVUnknowns.erase(V); } - virtual bool isLoopInvariant(const Loop *L) const { - // All non-instruction values are loop invariant. All instructions are - // loop invariant if they are not contained in the specified loop. - if (Instruction *I = dyn_cast(V)) - return !L->contains(I->getParent()); - return true; - } +bool SCEVUnknown::isLoopInvariant(const Loop *L) const { + // All non-instruction values are loop invariant. All instructions are loop + // invariant if they are not contained in the specified loop. + if (Instruction *I = dyn_cast(V)) + return !L->contains(I->getParent()); + return true; +} - virtual bool hasComputableLoopEvolution(const Loop *QL) const { - return false; // not computable - } +const Type *SCEVUnknown::getType() const { + return V->getType(); +} - virtual const Type *getType() const { return V->getType(); } +void SCEVUnknown::print(std::ostream &OS) const { + WriteAsOperand(OS, V, false); +} - virtual void print(std::ostream &OS) const { - WriteAsOperand(OS, V, false); - } - /// Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const SCEVUnknown *S) { return true; } - static inline bool classof(const SCEV *S) { - return S->getSCEVType() == scUnknown; - } - }; -} //===----------------------------------------------------------------------===// // Simple SCEV method implementations @@ -1372,6 +953,14 @@ SCEVAddRecExprs[std::make_pair(L, std::vector(Operands.begin(), Operands.end()))]; if (Result == 0) Result = new SCEVAddRecExpr(Operands, L); + return Result; +} + +SCEVHandle SCEVUnknown::get(Value *V) { + if (ConstantInt *CI = dyn_cast(V)) + return SCEVConstant::get(CI); + SCEVUnknown *&Result = SCEVUnknowns[V]; + if (Result == 0) Result = new SCEVUnknown(V); return Result; } From lattner at cs.uiuc.edu Thu Apr 15 10:16:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Apr 15 10:16:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/LoopInfo.h Message-ID: <200404151515.KAA26462@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: LoopInfo.h updated: 1.32 -> 1.33 --- Log message: Add some helpful methods --- Diffs of the changes: (+36 -5) Index: llvm/include/llvm/Analysis/LoopInfo.h diff -u llvm/include/llvm/Analysis/LoopInfo.h:1.32 llvm/include/llvm/Analysis/LoopInfo.h:1.33 --- llvm/include/llvm/Analysis/LoopInfo.h:1.32 Mon Apr 12 15:26:11 2004 +++ llvm/include/llvm/Analysis/LoopInfo.h Thu Apr 15 10:15:40 2004 @@ -33,6 +33,8 @@ class DominatorSet; class LoopInfo; +class PHINode; + class Instruction; //===----------------------------------------------------------------------===// /// Loop class - Instances of this class are used to represent loops that are @@ -94,17 +96,46 @@ return false; } + //===--------------------------------------------------------------------===// + // APIs for simple analysis of the loop. + // + // Note that all of these methods can fail on general loops (ie, there may not + // be a preheader, etc). For best success, the loop simplification and + // induction variable canonicalization pass should be used to normalize loops + // for easy analysis. These methods assume canonical loops. + /// getLoopPreheader - If there is a preheader for this loop, return it. A /// loop has a preheader if there is only one edge to the header of the loop /// from outside of the loop. If this is the case, the block branching to the - /// header of the loop is the preheader node. The "preheaders" pass can be - /// "Required" to ensure that there is always a preheader node for every loop. + /// header of the loop is the preheader node. /// - /// This method returns null if there is no preheader for the loop (either - /// because the loop is dead or because multiple blocks branch to the header - /// node of this loop). + /// This method returns null if there is no preheader for the loop. /// BasicBlock *getLoopPreheader() const; + + /// getCanonicalInductionVariable - Check to see if the loop has a canonical + /// induction variable: an integer recurrence that starts at 0 and increments + /// by one each time through the loop. If so, return the phi node that + /// corresponds to it. + /// + PHINode *getCanonicalInductionVariable() const; + + /// getCanonicalInductionVariableIncrement - Return the LLVM value that holds + /// the canonical induction variable value for the "next" iteration of the + /// loop. This always succeeds if getCanonicalInductionVariable succeeds. + /// + Instruction *getCanonicalInductionVariableIncrement() const; + + /// getTripCount - Return a loop-invariant LLVM value indicating the number of + /// times the loop will be executed. Note that this means that the backedge + /// of the loop executes N-1 times. If the trip-count cannot be determined, + /// this returns null. + /// + Value *getTripCount() const; + + //===--------------------------------------------------------------------===// + // APIs for updating loop information after changing the CFG + // /// addBasicBlockToLoop - This method is used by other analyses to update loop /// information. NewBB is set to be a new member of the current loop. From lattner at cs.uiuc.edu Thu Apr 15 10:16:09 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Apr 15 10:16:09 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/LoopInfo.cpp Message-ID: <200404151516.KAA26527@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: LoopInfo.cpp updated: 1.48 -> 1.49 --- Log message: add some helpful methods. Rearrange #includes to proper order --- Diffs of the changes: (+89 -6) Index: llvm/lib/Analysis/LoopInfo.cpp diff -u llvm/lib/Analysis/LoopInfo.cpp:1.48 llvm/lib/Analysis/LoopInfo.cpp:1.49 --- llvm/lib/Analysis/LoopInfo.cpp:1.48 Mon Apr 12 15:26:17 2004 +++ llvm/lib/Analysis/LoopInfo.cpp Thu Apr 15 10:16:02 2004 @@ -14,8 +14,10 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Constants.h" +#include "llvm/Instructions.h" +#include "llvm/Analysis/Dominators.h" #include "llvm/Assembly/Writer.h" #include "llvm/Support/CFG.h" #include "Support/DepthFirstIterator.h" @@ -313,15 +315,16 @@ "Loops already embedded into a subloop!"); } +//===----------------------------------------------------------------------===// +// APIs for simple analysis of the loop. +// + /// getLoopPreheader - If there is a preheader for this loop, return it. A /// loop has a preheader if there is only one edge to the header of the loop /// from outside of the loop. If this is the case, the block branching to the -/// header of the loop is the preheader node. The "preheaders" pass can be -/// "Required" to ensure that there is always a preheader node for every loop. +/// header of the loop is the preheader node. /// -/// This method returns null if there is no preheader for the loop (either -/// because the loop is dead or because multiple blocks branch to the header -/// node of this loop). +/// This method returns null if there is no preheader for the loop. /// BasicBlock *Loop::getLoopPreheader() const { // Keep track of nodes outside the loop branching to the header... @@ -348,6 +351,86 @@ // is still null. return Out; } + +/// getCanonicalInductionVariable - Check to see if the loop has a canonical +/// induction variable: an integer recurrence that starts at 0 and increments by +/// one each time through the loop. If so, return the phi node that corresponds +/// to it. +/// +PHINode *Loop::getCanonicalInductionVariable() const { + BasicBlock *H = getHeader(); + + BasicBlock *Incoming = 0, *Backedge = 0; + pred_iterator PI = pred_begin(H); + assert(PI != pred_end(H) && "Loop must have at least one backedge!"); + Backedge = *PI++; + if (PI == pred_end(H)) return 0; // dead loop + Incoming = *PI++; + if (PI != pred_end(H)) return 0; // multiple backedges? + + if (contains(Incoming)) { + if (contains(Backedge)) + return 0; + std::swap(Incoming, Backedge); + } else if (!contains(Backedge)) + return 0; + + // Loop over all of the PHI nodes, looking for a canonical indvar. + for (BasicBlock::iterator I = H->begin(); + PHINode *PN = dyn_cast(I); ++I) + if (Instruction *Inc = + dyn_cast(PN->getIncomingValueForBlock(Backedge))) + if (Inc->getOpcode() == Instruction::Add && Inc->getOperand(0) == PN) + if (ConstantInt *CI = dyn_cast(Inc->getOperand(1))) + if (CI->equalsInt(1)) + return PN; + + return 0; +} + +/// getCanonicalInductionVariableIncrement - Return the LLVM value that holds +/// the canonical induction variable value for the "next" iteration of the loop. +/// This always succeeds if getCanonicalInductionVariable succeeds. +/// +Instruction *Loop::getCanonicalInductionVariableIncrement() const { + if (PHINode *PN = getCanonicalInductionVariable()) { + bool P1InLoop = contains(PN->getIncomingBlock(1)); + return cast(PN->getIncomingValue(P1InLoop)); + } + return 0; +} + +/// getTripCount - Return a loop-invariant LLVM value indicating the number of +/// times the loop will be executed. Note that this means that the backedge of +/// the loop executes N-1 times. If the trip-count cannot be determined, this +/// returns null. +/// +Value *Loop::getTripCount() const { + // Canonical loops will end with a 'setne I, V', where I is the incremented + // canonical induction variable and V is the trip count of the loop. + Instruction *Inc = getCanonicalInductionVariableIncrement(); + PHINode *IV = cast(Inc->getOperand(0)); + + BasicBlock *BackedgeBlock = + 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) + return SCI->getOperand(1); + } else if (SCI->getOpcode() == Instruction::SetEQ) { + return SCI->getOperand(1); + } + + return 0; +} + + +//===-------------------------------------------------------------------===// +// APIs for updating loop information after changing the CFG +// /// addBasicBlockToLoop - This function is used by other analyses to update loop /// information. NewBB is set to be a new member of the current loop. Because From lattner at cs.uiuc.edu Thu Apr 15 10:22:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Apr 15 10:22:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <200404151521.KAA27519@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: IndVarSimplify.cpp updated: 1.53 -> 1.54 --- Log message: Change the canonical induction variable that we insert. Instead of producing code like this: Loop: X = phi 0, X2 ... X2 = X + 1 if (X != N-1) goto Loop We now generate code that looks like this: Loop: X = phi 0, X2 ... X2 = X + 1 if (X2 != N) goto Loop This has two big advantages: 1. The trip count of the loop is now explicit in the code, allowing the direct implementation of Loop::getTripCount() 2. This reduces register pressure in the loop, and allows X and X2 to be put into the same register. As a consequence of the second point, the code we generate for loops went from: .LBB2: # no_exit.1 ... mov %EDI, %ESI inc %EDI cmp %ESI, 2 mov %ESI, %EDI jne .LBB2 # PC rel: no_exit.1 To: .LBB2: # no_exit.1 ... inc %ESI cmp %ESI, 3 jne .LBB2 # PC rel: no_exit.1 ... which has two fewer moves, and uses one less register. --- Diffs of the changes: (+17 -10) Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp diff -u llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.53 llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.54 --- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.53 Fri Apr 2 14:24:31 2004 +++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Thu Apr 15 10:21:43 2004 @@ -39,10 +39,10 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/BasicBlock.h" -#include "llvm/Constant.h" +#include "llvm/Constants.h" #include "llvm/Instructions.h" #include "llvm/Type.h" -#include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Support/CFG.h" #include "llvm/Transforms/Utils/Local.h" @@ -85,7 +85,7 @@ void EliminatePointerRecurrence(PHINode *PN, BasicBlock *Preheader, std::set &DeadInsts); void LinearFunctionTestReplace(Loop *L, SCEV *IterationCount, - Value *IndVar, ScalarEvolutionRewriter &RW); + ScalarEvolutionRewriter &RW); void RewriteLoopExitValues(Loop *L); void DeleteTriviallyDeadInstructions(std::set &Insts); @@ -177,12 +177,11 @@ } /// LinearFunctionTestReplace - This method rewrites the exit condition of the -/// loop to be a canonical != comparison against the loop induction variable. -/// This pass is able to rewrite the exit tests of any loop where the SCEV -/// analysis can determine the trip count of the loop, which is actually a much -/// broader range than just linear tests. +/// loop to be a canonical != comparison against the incremented loop induction +/// variable. This pass is able to rewrite the exit tests of any loop where the +/// SCEV analysis can determine a loop-invariant trip count of the loop, which +/// is actually a much broader range than just linear tests. void IndVarSimplify::LinearFunctionTestReplace(Loop *L, SCEV *IterationCount, - Value *IndVar, ScalarEvolutionRewriter &RW) { // Find the exit block for the loop. We can currently only handle loops with // a single exit. @@ -210,9 +209,17 @@ if (Instruction *Cond = dyn_cast(BI->getCondition())) InstructionsToDelete.insert(Cond); + // The IterationCount expression contains the number of times that the + // backedge actually branches to the loop header. This is one less than the + // number of times the loop executes, so add one to it. + Constant *OneC = ConstantInt::get(IterationCount->getType(), 1); + SCEVHandle TripCount=SCEVAddExpr::get(IterationCount, SCEVUnknown::get(OneC)); + + Value *IndVar = L->getCanonicalInductionVariableIncrement(); + // Expand the code for the iteration count into the preheader of the loop. BasicBlock *Preheader = L->getLoopPreheader(); - Value *ExitCnt = RW.ExpandCodeFor(IterationCount, Preheader->getTerminator(), + Value *ExitCnt = RW.ExpandCodeFor(TripCount, Preheader->getTerminator(), IndVar->getType()); // Insert a new setne or seteq instruction before the branch. @@ -368,7 +375,7 @@ Changed = true; if (!isa(IterationCount)) - LinearFunctionTestReplace(L, IterationCount, IndVar, Rewriter); + LinearFunctionTestReplace(L, IterationCount, Rewriter); #if 0 // If there were induction variables of other sizes, cast the primary From brukman at cs.uiuc.edu Thu Apr 15 10:24:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Apr 15 10:24:01 2004 Subject: [llvm-commits] CVS: llvm/tools/gccld/Linker.cpp Message-ID: <200404151523.KAA27786@zion.cs.uiuc.edu> Changes in directory llvm/tools/gccld: Linker.cpp updated: 1.23 -> 1.24 --- Log message: Don't use invalid HTML in a doxygen comment. --- Diffs of the changes: (+1 -1) Index: llvm/tools/gccld/Linker.cpp diff -u llvm/tools/gccld/Linker.cpp:1.23 llvm/tools/gccld/Linker.cpp:1.24 --- llvm/tools/gccld/Linker.cpp:1.23 Mon Feb 23 16:42:51 2004 +++ llvm/tools/gccld/Linker.cpp Thu Apr 15 10:23:45 2004 @@ -34,7 +34,7 @@ /// FindLib - Try to convert Filename into the name of a file that we can open, /// if it does not already name a file we can open, by first trying to open -/// Filename, then libFilename. for each of a set of several common +/// Filename, then libFilename.[suffix] for each of a set of several common /// library suffixes, in each of the directories in Paths and the directory /// named by the value of the environment variable LLVM_LIB_SEARCH_PATH. Returns /// an empty string if no matching file can be found. From brukman at cs.uiuc.edu Thu Apr 15 10:25:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Apr 15 10:25:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Debugger/ProgramInfo.h Message-ID: <200404151525.KAA27881@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Debugger: ProgramInfo.h updated: 1.1 -> 1.2 --- Log message: Don't use invalid HTML in doxygen comments. --- Diffs of the changes: (+1 -1) Index: llvm/include/llvm/Debugger/ProgramInfo.h diff -u llvm/include/llvm/Debugger/ProgramInfo.h:1.1 llvm/include/llvm/Debugger/ProgramInfo.h:1.2 --- llvm/include/llvm/Debugger/ProgramInfo.h:1.1 Sun Jan 4 23:23:38 2004 +++ llvm/include/llvm/Debugger/ProgramInfo.h Thu Apr 15 10:24:55 2004 @@ -227,7 +227,7 @@ /// getLanguageCache - This method is used to build per-program caches of /// information, such as the functions or types visible to the program. /// This can be used by SourceLanguage implementations because it requires - /// an accessible ::CacheType typedef, where is the C++ type of the + /// an accessible [sl]::CacheType typedef, where [sl] is the C++ type of the /// source-language subclass. template typename SL::CacheType &getLanguageCache(const SL *L) { From brukman at cs.uiuc.edu Thu Apr 15 10:31:02 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Apr 15 10:31:02 2004 Subject: [llvm-commits] CVS: llvm/utils/TableGen/Record.h Message-ID: <200404151530.KAA29073@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: Record.h updated: 1.38 -> 1.39 --- Log message: The "best" of both worlds: readable C++ comments and valid HTML For doxygen. --- Diffs of the changes: (+7 -4) Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.38 llvm/utils/TableGen/Record.h:1.39 --- llvm/utils/TableGen/Record.h:1.38 Tue Nov 11 16:41:34 2003 +++ llvm/utils/TableGen/Record.h Thu Apr 15 10:30:15 2004 @@ -125,7 +125,8 @@ }; -/// BitsRecTy - 'bits' - Represent a fixed number of bits +// BitsRecTy - 'bits' - Represent a fixed number of bits +/// BitsRecTy - 'bits<n>' - Represent a fixed number of bits /// class BitsRecTy : public RecTy { unsigned Size; @@ -188,8 +189,10 @@ virtual bool baseClassOf(const StringRecTy *RHS) const { return true; } }; -/// ListRecTy - 'list' - Represent a list of values, all of which must be of -/// the specified type. +// ListRecTy - 'list' - Represent a list of values, all of which must be of +// the specified type. +/// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must +/// be of the specified type. /// class ListRecTy : public RecTy { RecTy *Ty; @@ -244,7 +247,7 @@ }; -/// RecordRecTy - '' - Represent an instance of a class, such as: +/// RecordRecTy - '[classname]' - Represent an instance of a class, such as: /// (R32 X = EAX). /// class RecordRecTy : public RecTy { From brukman at cs.uiuc.edu Thu Apr 15 10:34:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Apr 15 10:34:01 2004 Subject: [llvm-commits] CVS: llvm/docs/doxygen.cfg Message-ID: <200404151534.KAA29786@zion.cs.uiuc.edu> Changes in directory llvm/docs: doxygen.cfg updated: 1.7 -> 1.8 --- Log message: Removed obsolete doxygen options (they were blank anyway). --- Diffs of the changes: (+0 -35) Index: llvm/docs/doxygen.cfg diff -u llvm/docs/doxygen.cfg:1.7 llvm/docs/doxygen.cfg:1.8 --- llvm/docs/doxygen.cfg:1.7 Wed Dec 31 00:47:28 2003 +++ llvm/docs/doxygen.cfg Thu Apr 15 10:33:49 2004 @@ -861,38 +861,3 @@ # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO - -# The CGI_NAME tag should be the name of the CGI script that -# starts the search engine (doxysearch) with the correct parameters. -# A script with this name will be generated by doxygen. - -CGI_NAME = - -# The CGI_URL tag should be the absolute URL to the directory where the -# cgi binaries are located. See the documentation of your http daemon for -# details. - -CGI_URL = - -# The DOC_URL tag should be the absolute URL to the directory where the -# documentation is located. If left blank the absolute path to the -# documentation, with file:// prepended to it, will be used. - -DOC_URL = - -# The DOC_ABSPATH tag should be the absolute path to the directory where the -# documentation is located. If left blank the directory on the local machine -# will be used. - -DOC_ABSPATH = - -# The BIN_ABSPATH tag must point to the directory where the doxysearch binary -# is installed. - -BIN_ABSPATH = - -# The EXT_DOC_PATHS tag can be used to specify one or more paths to -# documentation generated for other projects. This allows doxysearch to search -# the documentation for these projects as well. - -EXT_DOC_PATHS = From brukman at cs.uiuc.edu Thu Apr 15 10:39:02 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Apr 15 10:39:02 2004 Subject: [llvm-commits] CVS: llvm/projects/Stacker/lib/compiler/StackerCompiler.h Message-ID: <200404151538.KAA09437@zion.cs.uiuc.edu> Changes in directory llvm/projects/Stacker/lib/compiler: StackerCompiler.h updated: 1.1 -> 1.2 --- Log message: If we're going to use tabs, use them consistently. Maybe doxygen will find the @parameter line documentation that way, too. --- Diffs of the changes: (+2 -2) Index: llvm/projects/Stacker/lib/compiler/StackerCompiler.h diff -u llvm/projects/Stacker/lib/compiler/StackerCompiler.h:1.1 llvm/projects/Stacker/lib/compiler/StackerCompiler.h:1.2 --- llvm/projects/Stacker/lib/compiler/StackerCompiler.h:1.1 Sun Nov 23 11:52:55 2003 +++ llvm/projects/Stacker/lib/compiler/StackerCompiler.h Thu Apr 15 10:38:48 2004 @@ -149,8 +149,8 @@ /// @name Utility functions /// @{ public: - /// @brief Throws an exception to indicate an error - /// @param message The message to be output + /// @brief Throws an exception to indicate an error + /// @param message The message to be output /// @param line Override for the current line no static inline void ThrowException( const std::string &message, int line = -1) From gaeke at cs.uiuc.edu Thu Apr 15 15:24:02 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Thu Apr 15 15:24:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9CodeEmitter.h Message-ID: <200404152023.PAA12066@seraph.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9CodeEmitter.h updated: 1.17 -> 1.18 --- Log message: Give SparcV9CodeEmitter a head-of-file comment and a PassName. --- Diffs of the changes: (+6 -1) Index: llvm/lib/Target/SparcV9/SparcV9CodeEmitter.h diff -u llvm/lib/Target/SparcV9/SparcV9CodeEmitter.h:1.17 llvm/lib/Target/SparcV9/SparcV9CodeEmitter.h:1.18 --- llvm/lib/Target/SparcV9/SparcV9CodeEmitter.h:1.17 Tue Nov 11 16:41:33 2003 +++ llvm/lib/Target/SparcV9/SparcV9CodeEmitter.h Thu Apr 15 15:23:13 2004 @@ -7,7 +7,10 @@ // //===----------------------------------------------------------------------===// // -// TODO: Need a description here. +// Target-specific portions of the machine code emitter for the SparcV9. +// This class interfaces with the JIT's Emitter in order to turn MachineInstrs +// into words of binary machine code. Its code is partially generated by +// TableGen's CodeEmitterGenerator. // //===----------------------------------------------------------------------===// @@ -39,6 +42,8 @@ public: SparcV9CodeEmitter(TargetMachine &T, MachineCodeEmitter &M); ~SparcV9CodeEmitter(); + + const char *getPassName() const { return "SparcV9 Machine Code Emitter"; } /// runOnMachineFunction - emits the given machine function to memory. /// From lattner at cs.uiuc.edu Thu Apr 15 15:27:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Apr 15 15:27:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <200404152026.PAA02435@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: IndVarSimplify.cpp updated: 1.54 -> 1.55 --- Log message: Fix a bug in the previous checkin: if the exit block is not the same as the back-edge block, we must check the preincremented value. --- Diffs of the changes: (+22 -6) Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp diff -u llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.54 llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.55 --- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.54 Thu Apr 15 10:21:43 2004 +++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Thu Apr 15 15:26:22 2004 @@ -209,13 +209,29 @@ if (Instruction *Cond = dyn_cast(BI->getCondition())) InstructionsToDelete.insert(Cond); - // The IterationCount expression contains the number of times that the - // backedge actually branches to the loop header. This is one less than the - // number of times the loop executes, so add one to it. - Constant *OneC = ConstantInt::get(IterationCount->getType(), 1); - SCEVHandle TripCount=SCEVAddExpr::get(IterationCount, SCEVUnknown::get(OneC)); + // If the exiting block is not the same as the backedge block, we must compare + // against the preincremented value, otherwise we prefer to compare against + // the post-incremented value. + BasicBlock *Header = L->getHeader(); + pred_iterator HPI = pred_begin(Header); + assert(HPI != pred_end(Header) && "Loop with zero preds???"); + if (!L->contains(*HPI)) ++HPI; + assert(HPI != pred_end(Header) && L->contains(*HPI) && + "No backedge in loop?"); - Value *IndVar = L->getCanonicalInductionVariableIncrement(); + SCEVHandle TripCount = IterationCount; + Value *IndVar; + if (*HPI == ExitingBlock) { + // The IterationCount expression contains the number of times that the + // backedge actually branches to the loop header. This is one less than the + // number of times the loop executes, so add one to it. + Constant *OneC = ConstantInt::get(IterationCount->getType(), 1); + TripCount = SCEVAddExpr::get(IterationCount, SCEVUnknown::get(OneC)); + IndVar = L->getCanonicalInductionVariableIncrement(); + } else { + // We have to use the preincremented value... + IndVar = L->getCanonicalInductionVariable(); + } // Expand the code for the iteration count into the preheader of the loop. BasicBlock *Preheader = L->getLoopPreheader(); From lattner at cs.uiuc.edu Thu Apr 15 15:46:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Apr 15 15:46:01 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/Inline/2004-04-15-InlineDeletesCall.ll Message-ID: <200404152045.PAA06126@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/Inline: 2004-04-15-InlineDeletesCall.ll added (r1.1) --- Log message: New testcase that Brian provided which crashes the inliner --- Diffs of the changes: (+21 -0) Index: llvm/test/Regression/Transforms/Inline/2004-04-15-InlineDeletesCall.ll diff -c /dev/null llvm/test/Regression/Transforms/Inline/2004-04-15-InlineDeletesCall.ll:1.1 *** /dev/null Thu Apr 15 15:45:56 2004 --- llvm/test/Regression/Transforms/Inline/2004-04-15-InlineDeletesCall.ll Thu Apr 15 15:45:45 2004 *************** *** 0 **** --- 1,21 ---- + ; RUN: llvm-as < %s | opt -inline -disable-output + + ; Inlining the first call caused the inliner function to delete the second + ; call. Then the inliner tries to inline the second call, which no longer + ; exists. + + implementation + + internal void %Callee1() { + unwind + } + + void %Callee2() { + ret void + } + + void %caller() { + call void %Callee1() + call void %Callee2() + ret void + } From brukman at cs.uiuc.edu Thu Apr 15 15:50:02 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Apr 15 15:50:02 2004 Subject: [llvm-commits] CVS: llvm/docs/HowToSubmitABug.html llvm.css Message-ID: <200404152049.PAA10980@zion.cs.uiuc.edu> Changes in directory llvm/docs: HowToSubmitABug.html updated: 1.13 -> 1.14 llvm.css updated: 1.12 -> 1.13 --- Log message: Add note about passing arguments to program being debugged. --- Diffs of the changes: (+47 -38) Index: llvm/docs/HowToSubmitABug.html diff -u llvm/docs/HowToSubmitABug.html:1.13 llvm/docs/HowToSubmitABug.html:1.14 --- llvm/docs/HowToSubmitABug.html:1.13 Fri Mar 12 14:42:16 2004 +++ llvm/docs/HowToSubmitABug.html Thu Apr 15 15:49:32 2004 @@ -147,9 +147,10 @@ compilation, compile your test-case to a .s file with the -save-temps option to llvm-gcc. Then run:

    -
    -  gccas -debug-pass=Arguments < /dev/null -o - > /dev/null
    -
    +
    +

    gccas -debug-pass=Arguments < /dev/null -o - > /dev/null +

    +

    ... which will print a list of arguments, indicating the list of passes that gccas runs. Once you have the input file and the list of @@ -170,10 +171,10 @@ being linked together (the "llvm-gcc -v" output should include the full list of objects linked). Then run:

    -
    -  llvm-as < /dev/null > null.bc
    -  gccld -debug-pass=Arguments null.bc
    -

    +

    +

    llvm-as < /dev/null > null.bc + gccld -debug-pass=Arguments null.bc

    +

    ... which will print a list of arguments, indicating the list of passes that gccld runs. Once you have the input files and the list of @@ -194,9 +195,9 @@ order to reduce the list of passes (which is probably large) and the input to something tractable, use the bugpoint tool as follows:

    -
    -  bugpoint <input files> <list of passes>
    -

    +

    +

    bugpoint <input files> <list of passes>

    +

    bugpoint will print a bunch of output as it reduces the test-case, but it should eventually print something like this:

    @@ -231,9 +232,10 @@ the output through, e.g. C backend, the JIT, or LLC, and a selection of passes, one of which may be causing the error, and run, for example:

    -
    -  bugpoint -run-cbe [... optimization passes ...] file-to-test.bc
    -
    +
    +

    bugpoint -run-cbe [... optimization passes ...] file-to-test.bc +--args -- [program arguments]

    +

    bugpoint will try to narrow down your list of passes to the one pass that causes an error, and simplify the bytecode file as much as it can to assist @@ -260,15 +262,17 @@

    To debug the JIT:

    -
    -  bugpoint -run-jit -output=[correct output file] [bytecodefile]
    -
    +
    +

    bugpoint -run-jit -output=[correct output file] [bytecode file] +--args -- [program arguments]

    +

    Similarly, to debug the LLC, one would run:

    -
    -  bugpoint -run-llc -output=[correct output file] [bytecodefile]
    -
    +
    +

    bugpoint -run-llc -output=[correct output file] [bytecode file] +--args -- [program arguments]

    +

    At the end of a successful bugpoint run, you will be presented with two bytecode files: a safe file which can be compiled with the C @@ -280,27 +284,28 @@

      -
    1. Regenerate the shared object from the safe bytecode file:
      +
    2. Regenerate the shared object from the safe bytecode file:

      -
      -  llc -march=c safe.bc -o safe.c
      - gcc -shared safe.c -o safe.so -
    3. - -
    4. If debugging LLC, compile test bytecode native and link with the shared object:
      - -
      -  llc test.bc -o test.s -f
      - gcc test.s safe.so -o test.llc
      - ./test.llc [program options] -
    5. +
      +

      llc -march=c safe.bc -o safe.c
      + gcc -shared safe.c -o safe.so

      +
      + +
    6. If debugging LLC, compile test bytecode native and link with the shared + object:

      + +
      +

      llc test.bc -o test.s -f
      + gcc test.s safe.so -o test.llc
      + ./test.llc [program options]

      +
    7. -
    8. If debugging the JIT, load the shared object and supply the test -bytecode: +
    9. If debugging the JIT, load the shared object and supply the test + bytecode:

      -
      -  lli -load=safe.so test.bc [program options]
      -
    10. +
      +

      lli -load=safe.so test.bc [program options]

      +
    @@ -317,7 +322,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/03/12 20:42:16 $ + Last modified: $Date: 2004/04/15 20:49:32 $ Index: llvm/docs/llvm.css diff -u llvm/docs/llvm.css:1.12 llvm/docs/llvm.css:1.13 --- llvm/docs/llvm.css:1.12 Mon Apr 5 22:53:49 2004 +++ llvm/docs/llvm.css Thu Apr 15 15:49:32 2004 @@ -51,3 +51,7 @@ padding: 1px 1px 1px 1px; border: 1px; } .doc_warning { color: red; font-weight: bold } + +.doc_code { border: solid 1px gray; background: #eeeeee; + width: 700px; margin: 0 0 0 1em; + padding: 0 0 0 1em } From alkis at cs.uiuc.edu Thu Apr 15 16:01:00 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 16:01:00 2004 Subject: [llvm-commits] CVS: llvm-java/tools/Makefile Message-ID: <200404152101.QAA10587@zion.cs.uiuc.edu> Changes in directory llvm-java/tools: Makefile added (r1.1) --- Log message: Initial checking of the llvm java-frontend. This contains a skeleton and a preliminary ClassFile parsing library --- Diffs of the changes: (+13 -0) Index: llvm-java/tools/Makefile diff -c /dev/null llvm-java/tools/Makefile:1.1 *** /dev/null Thu Apr 15 16:01:00 2004 --- llvm-java/tools/Makefile Thu Apr 15 16:00:50 2004 *************** *** 0 **** --- 1,13 ---- + ##===- tools/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 := .. + PARALLEL_DIRS := classdump + + include $(LEVEL)/Makefile.common From alkis at cs.uiuc.edu Thu Apr 15 16:01:10 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 16:01:10 2004 Subject: [llvm-commits] CVS: llvm-java/lib/ClassFile/ClassFile.cpp Makefile Message-ID: <200404152101.QAA10580@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/ClassFile: ClassFile.cpp added (r1.1) Makefile added (r1.1) --- Log message: Initial checking of the llvm java-frontend. This contains a skeleton and a preliminary ClassFile parsing library --- Diffs of the changes: (+386 -0) Index: llvm-java/lib/ClassFile/ClassFile.cpp diff -c /dev/null llvm-java/lib/ClassFile/ClassFile.cpp:1.1 *** /dev/null Thu Apr 15 16:01:00 2004 --- llvm-java/lib/ClassFile/ClassFile.cpp Thu Apr 15 16:00:50 2004 *************** *** 0 **** --- 1,372 ---- + //===-- ClassFile.cpp - ClassFile class -----------------------------------===// + // + // 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 contains the implementation of the ClassFile library. It + // is used by the LLVM Java frontend to parse Java Class files. + // + //===----------------------------------------------------------------------===// + + #include + + #include + #include + #include + #include + + using namespace llvm::Java; + + //===----------------------------------------------------------------------===// + // Utility functions + namespace { + + char bool2cross(bool v) + { + return v ? 'x' : ' '; + } + + uint8_t readU1(std::istream& is) { + char val; + if (!is.get(val)) + throw ClassFileParseError("unexpected end of input"); + return val; + } + + uint16_t readU2(std::istream& is) { + return (readU1(is) << 8) | readU1(is); + } + + uint32_t readU4(std::istream& is) { + return (readU2(is) << 16) | readU2(is); + } + + uint64_t readU8(std::istream& is) { + uint64_t hi = readU4(is), lo = readU4(is); + return hi << 32 | lo; + } + + float int2float(uint32_t v) { + union { uint32_t in; float out; } tmp; + tmp.in = v; + return tmp.out; + } + + double long2double(uint64_t v) { + union { uint64_t in; double out; } tmp; + tmp.in = v; + return tmp.out; + } + + }; + + //===----------------------------------------------------------------------===// + // ClassFileParseError implementation + ClassFileParseError::~ClassFileParseError() throw() + { + + } + + //===----------------------------------------------------------------------===// + // Constant implementation + Constant* Constant::readConstant(const ClassFile::ConstantPool& cp, + std::istream& is) + { + Constant::Tag tag = static_cast(readU1(is)); + switch (tag) { + case Constant::CLASS: + return new ConstantClass(cp, is); + case Constant::FIELD_REF: + return new ConstantFieldRef(cp, is); + case Constant::METHOD_REF: + return new ConstantMethodRef(cp, is); + case Constant::INTERFACE_METHOD_REF: + return new ConstantInterfaceMethodRef(cp, is); + case Constant::STRING: + return new ConstantString(cp, is); + case Constant::INTEGER: + return new ConstantInteger(cp, is); + case Constant::FLOAT: + return new ConstantFloat(cp, is); + case Constant::LONG: + return new ConstantLong(cp, is); + case Constant::DOUBLE: + return new ConstantDouble(cp, is); + case Constant::NAME_AND_TYPE: + return new ConstantNameAndType(cp, is); + case Constant::UTF8: + return new ConstantUtf8(cp, is); + default: + assert(0 && "Unknown constant tag"); + } + + return NULL; + } + + Constant::~Constant() + { + + } + + std::ostream& Constant::dump(std::ostream& os) const + { + // FIXME + return os; + } + + ConstantMemberRef::ConstantMemberRef(const ClassFile::ConstantPool&cp, + std::istream& is) + : Constant(cp), + classIdx_(readU2(is)), + nameAndTypeIdx_(readU2(is)) + { + + } + + ConstantClass::ConstantClass(const ClassFile::ConstantPool& cp, + std::istream& is) + : Constant(cp), + nameIdx_(readU2(is)) + { + + } + + ConstantString::ConstantString(const ClassFile::ConstantPool& cp, + std::istream& is) + : Constant(cp), + stringIdx_(readU2(is)) + { + + } + + ConstantInteger::ConstantInteger(const ClassFile::ConstantPool& cp, + std::istream& is) + : Constant(cp), + value_(static_cast(readU4(is))) + { + + } + + ConstantFloat::ConstantFloat(const ClassFile::ConstantPool& cp, + std::istream& is) + : Constant(cp), + value_(int2float(readU4(is))) + { + + } + + ConstantLong::ConstantLong(const ClassFile::ConstantPool& cp, + std::istream& is) + : Constant(cp), + value_(static_cast(readU8(is))) + { + + } + + ConstantDouble::ConstantDouble(const ClassFile::ConstantPool& cp, + std::istream& is) + : Constant(cp), + value_(long2double(readU8(is))) + { + + } + + ConstantNameAndType::ConstantNameAndType(const ClassFile::ConstantPool& cp, + std::istream& is) + : Constant(cp), + nameIdx_(readU2(is)), + descriptorIdx_(readU2(is)) + { + + } + + ConstantUtf8::ConstantUtf8(const ClassFile::ConstantPool& cp, + std::istream& is) + : Constant(cp) + { + uint16_t length = readU2(is); + char buf[length]; + is.read(buf, length); + utf8_ = std::string(buf, length); + } + + //===----------------------------------------------------------------------===// + // Field implementation + Field::Field(const ClassFile::ConstantPool& cp, std::istream& is) + { + accessFlags_ = readU2(is); + name_ = dynamic_cast(cp[readU2(is)]); + if (!name_) throw "FIXME: better error message"; + descriptor_ = dynamic_cast(cp[readU2(is)]); + } + + std::ostream& Field::dump(std::ostream& os) const + { + // FIXME + return os; + } + + //===----------------------------------------------------------------------===// + // Method implementation + Method::Method(const ClassFile::ConstantPool& cp, std::istream& is) + { + accessFlags_ = readU2(is); + name_ = dynamic_cast(cp[readU2(is)]); + if (!name_) throw "FIXME: better error message"; + descriptor_ = dynamic_cast(cp[readU2(is)]); + } + + std::ostream& Method::dump(std::ostream& os) const + { + // FIXME + return os; + } + + //===----------------------------------------------------------------------===// + // Attribute implementation + Attribute::Attribute(const ClassFile::ConstantPool& cp, std::istream& is) + { + name_ = dynamic_cast(cp[readU2(is)]); + if (!name_) throw "FIXME: better error message"; + uint32_t length = readU4(is); + is.ignore(length); + } + + Attribute* Attribute::readAttribute(const ClassFile::ConstantPool& cp, + std::istream& is) + { + return new Attribute(cp, is); + } + + std::ostream& Attribute::dump(std::ostream& os) const + { + // FIXME + return os; + } + + //===----------------------------------------------------------------------===// + // ClassFile implementation + ClassFile* ClassFile::readClassFile(std::istream& is) + { + if (readU1(is) != 0xCA) throw ClassFileParseError("bad magic"); + if (readU1(is) != 0xFE) throw ClassFileParseError("bad magic"); + if (readU1(is) != 0xBA) throw ClassFileParseError("bad magic"); + if (readU1(is) != 0xBE) throw ClassFileParseError("bad magic"); + + return new ClassFile(is); + } + + namespace { + + void readConstantPool(ClassFile::ConstantPool& cp, std::istream& is) + { + assert(cp.empty() && "Should not call with a non-empty constant pool"); + uint16_t count = readU2(is) - 1; + cp.reserve(count); + while (count--) + cp.push_back(Constant::readConstant(cp, is)); + } + + void readInterfaces(ClassFile::Interfaces& i, + const ClassFile::ConstantPool& cp, + std::istream& is) + { + assert(i.empty() && + "Should not call with a non-empty interfaces vector"); + uint16_t count = readU2(is); + i.reserve(count); + while (count--) { + ConstantClass* c = dynamic_cast(cp[readU2(is)]); + if (!c) throw "FIXME: give better error message"; + i.push_back(c); + } + } + + void readFields(ClassFile::Fields& f, + const ClassFile::ConstantPool& cp, + std::istream& is) + { + assert(f.empty() && "Should not call with a non-empty fields vector"); + uint16_t count = readU2(is); + f.reserve(count); + while(count--) + f.push_back(Field::readField(cp, is)); + } + + void readMethods(ClassFile::Methods& m, + const ClassFile::ConstantPool& cp, + std::istream& is) + { + assert(m.empty() && "Should not call with a non-empty methods vector"); + uint16_t count = readU2(is); + m.reserve(count); + while(count--) + m.push_back(Method::readMethod(cp, is)); + } + + void readAttributes(ClassFile::Attributes& a, + const ClassFile::ConstantPool& cp, + std::istream& is) + { + assert(a.empty() && + "Should not call with a non-empty attributes vector"); + uint16_t count = readU2(is); + a.reserve(count); + while(count--) + a.push_back(Attribute::readAttribute(cp, is)); + } + + } + + ClassFile::ClassFile(std::istream& is) + { + minorV_ = readU2(is); + majorV_ = readU2(is); + readConstantPool(cPool_, is); + accessFlags_ = readU2(is); + thisClass_ = dynamic_cast(cPool_[readU2(is)]); + if (!thisClass_) throw "FIXME: better error message"; + superClass_ = dynamic_cast(cPool_[readU2(is)]); + if (!superClass_) throw "FIXME: better error message"; + readInterfaces(interfaces_, cPool_, is); + readFields(fields_, cPool_, is); + readMethods(methods_, cPool_, is); + readAttributes(attributes_, cPool_, is); + } + + std::ostream& ClassFile::dump(std::ostream& os) const + { + os << "Minor version: " << getMinorVersion() << '\n' + << "Major version: " << getMajorVersion() << '\n' + << "Access flags (PFSIA): " + << bool2cross(isPublic()) + << bool2cross(isFinal()) + + << bool2cross(isSuper()) + << bool2cross(isInterface()) + << bool2cross(isAbstract()) << '\n' + << "This class: " << getThisClass() << '\n' + << "Super class: " << getSuperClass() << '\n'; + + for (Interfaces::const_iterator + i = interfaces_.begin(), e = interfaces_.end(); i != e; ++i) + (*i)->dump(os); + + for (Fields::const_iterator + i = fields_.begin(), e = fields_.end(); i != e; ++i) + (*i)->dump(os); + + for (Methods::const_iterator + i = methods_.begin(), e = methods_.end(); i != e; ++i) + (*i)->dump(os); + + for (Attributes::const_iterator + i = attributes_.begin(), e = attributes_.end(); i != e; ++i) + (*i)->dump(os); + + return os; + } Index: llvm-java/lib/ClassFile/Makefile diff -c /dev/null llvm-java/lib/ClassFile/Makefile:1.1 *** /dev/null Thu Apr 15 16:01:00 2004 --- llvm-java/lib/ClassFile/Makefile Thu Apr 15 16:00:50 2004 *************** *** 0 **** --- 1,14 ---- + ##===- lib/Analysis/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 = classfile + #BUILD_ARCHIVE = 1 + + include $(LEVEL)/Makefile.common From alkis at cs.uiuc.edu Thu Apr 15 16:01:17 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 16:01:17 2004 Subject: [llvm-commits] CVS: llvm-java/include/llvm/Java/ClassFile.h Message-ID: <200404152101.QAA10564@zion.cs.uiuc.edu> Changes in directory llvm-java/include/llvm/Java: ClassFile.h added (r1.1) --- Log message: Initial checking of the llvm java-frontend. This contains a skeleton and a preliminary ClassFile parsing library --- Diffs of the changes: (+312 -0) Index: llvm-java/include/llvm/Java/ClassFile.h diff -c /dev/null llvm-java/include/llvm/Java/ClassFile.h:1.1 *** /dev/null Thu Apr 15 16:01:00 2004 --- llvm-java/include/llvm/Java/ClassFile.h Thu Apr 15 16:00:50 2004 *************** *** 0 **** --- 1,312 ---- + //===-- ClassFile.h - ClassFile support library -----------------*- 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 file contains the declaration of the ClassFileReader class, + // which implements a ClassFile reader parser for use with the Java + // frontend. + // + //===----------------------------------------------------------------------===// + + #include + #include + #include + + #include + + namespace llvm { namespace Java { + + // Forward declarations + class Attribute; + class Constant; + class ConstantClass; + class ConstantNameAndType; + class ConstantUtf8; + class ClassFile; + class Field; + class Method; + + enum AccessFlag { + ACC_PUBLIC = 0x0001, + ACC_PRIVATE = 0x0002, + ACC_PROTECTED = 0x0004, + ACC_STATIC = 0x0008, + ACC_FINAL = 0x0010, + ACC_SUPER = 0x0020, + ACC_SYNCHRONIZED = 0x0020, + ACC_VOLATILE = 0x0040, + ACC_TRANSIENT = 0x0080, + ACC_NATIVE = 0x0100, + ACC_INTERFACE = 0x0200, + ACC_ABSTRACT = 0x0400, + ACC_STRICT = 0x0800, + }; + + class ClassFile { + public: + typedef std::vector ConstantPool; + typedef std::vector Interfaces; + typedef std::vector Fields; + typedef std::vector Methods; + typedef std::vector Attributes; + + public: + static ClassFile* readClassFile(std::istream& is); + + uint16_t getMinorVersion() const { return minorV_; } + uint16_t getMajorVersion() const { return majorV_; } + + const ConstantPool& getConstantPool() const { return cPool_; } + + bool isPublic() const { return accessFlags_ & ACC_PUBLIC; } + bool isFinal() const { return accessFlags_ & ACC_FINAL; } + bool isSuper() const { return accessFlags_ & ACC_SUPER; } + bool isInterface() const { return accessFlags_ & ACC_INTERFACE; } + bool isAbstract() const { return accessFlags_ & ACC_ABSTRACT; } + + const ConstantClass* getThisClass() const { return thisClass_; } + const ConstantClass* getSuperClass() const { return superClass_; } + + const Interfaces& getInterfaces() const; + + const Fields& getFields() const; + + const Methods& getMethods() const; + + const Attributes& getAttributes() const; + + std::ostream& dump(std::ostream& os) const; + + private: + uint16_t majorV_; + uint16_t minorV_; + ConstantPool cPool_; + uint16_t accessFlags_; + ConstantClass* thisClass_; + ConstantClass* superClass_; + Interfaces interfaces_; + Fields fields_; + Methods methods_; + Attributes attributes_; + + ClassFile(std::istream& is); + }; + + class Constant { + protected: + const ClassFile::ConstantPool& cPool_; + + Constant(const ClassFile::ConstantPool& cp) + : cPool_(cp) { } + + public: + enum Tag { + CLASS = 7, + FIELD_REF = 9, + METHOD_REF = 10, + INTERFACE_METHOD_REF = 11, + STRING = 8, + INTEGER = 3, + FLOAT = 4, + LONG = 5, + DOUBLE = 6, + NAME_AND_TYPE = 12, + UTF8 = 1 + }; + + static Constant* readConstant(const ClassFile::ConstantPool& cp, + std::istream& is); + + virtual ~Constant(); + + virtual std::ostream& dump(std::ostream& os) const; + }; + + class ConstantClass : public Constant { + uint16_t nameIdx_; + public: + ConstantClass(const ClassFile::ConstantPool& cp, std::istream& is); + const ConstantUtf8* getName() const { + return (const ConstantUtf8*) cPool_[nameIdx_]; + } + }; + + class ConstantMemberRef : public Constant { + uint16_t classIdx_; + uint16_t nameAndTypeIdx_; + protected: + ConstantMemberRef(const ClassFile::ConstantPool& cp, std::istream& is); + + public: + const ConstantClass* getClass() const { + return (const ConstantClass*) cPool_[classIdx_]; + } + const ConstantNameAndType* getNameAndType() const { + return (const ConstantNameAndType*) cPool_[nameAndTypeIdx_]; + } + }; + + struct ConstantFieldRef : public ConstantMemberRef { + ConstantFieldRef(const ClassFile::ConstantPool& cp, std::istream& is) + : ConstantMemberRef(cp, is) { } + }; + + struct ConstantMethodRef : public ConstantMemberRef { + ConstantMethodRef(const ClassFile::ConstantPool& cp, std::istream& is) + : ConstantMemberRef(cp, is) { } + }; + + struct ConstantInterfaceMethodRef : public ConstantMemberRef { + ConstantInterfaceMethodRef(const ClassFile::ConstantPool& cp, + std::istream& is) + : ConstantMemberRef(cp, is) { } + }; + + class ConstantString : public Constant { + uint16_t stringIdx_; + public: + ConstantString(const ClassFile::ConstantPool& cp, std::istream& is); + const ConstantUtf8* getValue() const { + return (const ConstantUtf8*) cPool_[stringIdx_]; + } + }; + + class ConstantInteger : public Constant { + int32_t value_; + public: + ConstantInteger(const ClassFile::ConstantPool& cp, std::istream& is); + int32_t getValue() const { return value_; } + }; + + class ConstantFloat : public Constant { + float value_; + public: + ConstantFloat(const ClassFile::ConstantPool& cp, std::istream& is); + float getValue() const { return value_; } + }; + + class ConstantLong : public Constant { + int64_t value_; + public: + ConstantLong(const ClassFile::ConstantPool& cp, std::istream& is); + int64_t getValue() const { return value_; } + }; + + class ConstantDouble : public Constant { + double value_; + public: + ConstantDouble(const ClassFile::ConstantPool& cp, std::istream& is); + double getValue() const { return value_; } + }; + + class ConstantNameAndType : public Constant { + uint16_t nameIdx_; + uint16_t descriptorIdx_; + public: + ConstantNameAndType(const ClassFile::ConstantPool& cp, std::istream& is); + const ConstantUtf8* getName() const { + return (const ConstantUtf8*) cPool_[nameIdx_]; + } + const ConstantUtf8* getDescriptor() const { + return (const ConstantUtf8*) cPool_[descriptorIdx_]; + } + }; + + class ConstantUtf8 : public Constant { + std::string utf8_; + public: + ConstantUtf8(const ClassFile::ConstantPool& cp, std::istream& is); + //const std::string& getUtf8() const { return utf8_; } + }; + + class Field { + public: + typedef std::vector Attributes; + + private: + uint16_t accessFlags_; + ConstantUtf8* name_; + ConstantUtf8* descriptor_; + Attributes attrs_; + + Field(const ClassFile::ConstantPool& cp, std::istream& is); + + public: + static Field* readField(const ClassFile::ConstantPool& cp, + std::istream& is) { + return new Field(cp, is); + } + + bool isPublic() const { return accessFlags_ & ACC_PUBLIC; } + bool isPrivate() const { return accessFlags_ & ACC_PRIVATE; } + bool isProtected() const { return accessFlags_ & ACC_PROTECTED; } + bool isStatic() const { return accessFlags_ & ACC_STATIC; } + bool isFinal() const { return accessFlags_ & ACC_FINAL; } + bool isVolatile() const { return accessFlags_ & ACC_VOLATILE; } + bool isTransient() const { return accessFlags_ & ACC_TRANSIENT; } + + ConstantUtf8* getName() const { return name_; } + ConstantUtf8* getDescriptorIdx() const { return descriptor_; } + + std::ostream& dump(std::ostream& os) const; + }; + + class Method { + uint16_t accessFlags_; + ConstantUtf8* name_; + ConstantUtf8* descriptor_; + ClassFile::Attributes attrs_; + + Method(const ClassFile::ConstantPool& cp, std::istream& is); + + public: + static Method* readMethod(const ClassFile::ConstantPool& cp, + std::istream& is) { + return new Method(cp, is); + } + + bool isPublic() const { return accessFlags_ & ACC_PUBLIC; } + bool isPrivate() const { return accessFlags_ & ACC_PRIVATE; } + bool isProtected() const { return accessFlags_ & ACC_PROTECTED; } + bool isStatic() const { return accessFlags_ & ACC_STATIC; } + bool isFinal() const { return accessFlags_ & ACC_FINAL; } + bool isSynchronized() const { return accessFlags_ & ACC_SYNCHRONIZED; } + bool isNative() const { return accessFlags_ & ACC_NATIVE; } + bool isAbstract() const { return accessFlags_ & ACC_ABSTRACT; } + bool isStrict() const { return accessFlags_ & ACC_STRICT; } + + ConstantUtf8* getName() const { return name_; } + ConstantUtf8* getDescriptor() const { return descriptor_; } + + std::ostream& dump(std::ostream& os) const; + }; + + class Attribute { + ConstantUtf8* name_; + + protected: + Attribute(const ClassFile::ConstantPool& cp, std::istream& is); + + public: + static Attribute* readAttribute(const ClassFile::ConstantPool& cp, + std::istream& is); + + ConstantUtf8* getName() const { return name_; } + + std::ostream& dump(std::ostream& os) const; + }; + + class ClassFileParseError : public std::exception { + std::string msg_; + public: + explicit ClassFileParseError(const std::string& msg) : msg_(msg) { } + virtual ~ClassFileParseError() throw(); + virtual const char* what() const throw() { return msg_.c_str(); } + }; + + } } // namespace llvm::Java From alkis at cs.uiuc.edu Thu Apr 15 16:01:24 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 16:01:24 2004 Subject: [llvm-commits] CVS: llvm-java/docs/object-layout.txt Message-ID: <200404152101.QAA10526@zion.cs.uiuc.edu> Changes in directory llvm-java/docs: object-layout.txt added (r1.1) --- Log message: Initial checking of the llvm java-frontend. This contains a skeleton and a preliminary ClassFile parsing library --- Diffs of the changes: (+59 -0) Index: llvm-java/docs/object-layout.txt diff -c /dev/null llvm-java/docs/object-layout.txt:1.1 *** /dev/null Thu Apr 15 16:01:00 2004 --- llvm-java/docs/object-layout.txt Thu Apr 15 16:00:49 2004 *************** *** 0 **** --- 1,59 ---- + Object layout for Java objects and array objects + ------------------------------------------------ + + 1) objects + + Need extensible header for the use of: + + a) VM: locking, hashing, dynamic type checking, virtual function + invocation. + + b) GC: garbage collection (can be the reference count for a + reference counting garbage collector) + + obj_t : { , , , ..., } + + +--------+ <-- pointer to object + | header | + +--------+ + | field1 | + +--------+ + | field2 | + +--------+ + | ...... | + +--------+ + | fieldN | + +--------+ + + 2) arrays + + +--------+ <-- pointer to array object + | len | + +--------+ + | header | + +--------+ + | obj_t* | + +--------+ + | ...... | + +--------+ + | ...... | + +--------+ + + array_object_t : { uint, , [ 0 x * ] } + + + Type information for java objects + --------------------------------- + + VM_Class object for each class. This object needs at least the + following fields: + + a) pointer to VM_Class object of its super class + b) list of interfaces implemented + c) list of field descriptors + d) list of methods (static, constructor, virtual, finalizer) + e) list of attributes (constant value, code, exceptions, inner + classes, synthetic, source file, line number table, local variable + table, deprecated) + + We would most likely need a method dispatch table as well (vtable). From alkis at cs.uiuc.edu Thu Apr 15 16:01:32 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 16:01:32 2004 Subject: [llvm-commits] CVS: llvm-java/Makefile Makefile.common.in configure Message-ID: <200404152101.QAA10508@zion.cs.uiuc.edu> Changes in directory llvm-java: Makefile added (r1.1) Makefile.common.in added (r1.1) configure added (r1.1) --- Log message: Initial checking of the llvm java-frontend. This contains a skeleton and a preliminary ClassFile parsing library --- Diffs of the changes: (+2393 -0) Index: llvm-java/Makefile diff -c /dev/null llvm-java/Makefile:1.1 *** /dev/null Thu Apr 15 16:00:59 2004 --- llvm-java/Makefile Thu Apr 15 16:00:49 2004 *************** *** 0 **** --- 1,13 ---- + ##===- ./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 = . + + DIRS = lib tools + + include $(LEVEL)/Makefile.common Index: llvm-java/Makefile.common.in diff -c /dev/null llvm-java/Makefile.common.in:1.1 *** /dev/null Thu Apr 15 16:00:59 2004 --- llvm-java/Makefile.common.in Thu Apr 15 16:00:49 2004 *************** *** 0 **** --- 1,30 ---- + #===-- Makefile.common - Common make rules for LLVM -------*- 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. + # + ##===----------------------------------------------------------------------===# + # + # Configure the location of the LLVM object root. We know it is two + # directories up. The source tree location we do not know; let the LLVM + # Makefiles find it for us. + # + LLVM_OBJ_ROOT=$(LEVEL)/../.. + + # + # Grab the LLVM configuration file. + # + include $(LEVEL)/../../Makefile.config + + # + # Reconfigure the source directories + # + BUILD_SRC_ROOT:=$(LLVM_SRC_ROOT)/projects/Java + BUILD_SRC_DIR := $(subst //,/,$(BUILD_SRC_ROOT)/$(patsubst $(BUILD_OBJ_ROOT)%,%, $(BUILD_OBJ_DIR))) + + # + # Include LLVM's build rules. + # + include $(LLVM_SRC_ROOT)/Makefile.rules Index: llvm-java/configure diff -c /dev/null llvm-java/configure:1.1 *** /dev/null Thu Apr 15 16:00:59 2004 --- llvm-java/configure Thu Apr 15 16:00:49 2004 *************** *** 0 **** --- 1,2350 ---- + #! /bin/sh + # Guess values for system-dependent variables and create Makefiles. + # Generated by GNU Autoconf 2.58 for [ModuleMaker] [x.xx]. + # + # Report bugs to . + # + # Copyright (C) 2003 Free Software Foundation, Inc. + # This configure script is free software; the Free Software Foundation + # gives unlimited permission to copy, distribute and modify it. + ## --------------------- ## + ## M4sh Initialization. ## + ## --------------------- ## + + # Be Bourne compatible + if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix + fi + DUALCASE=1; export DUALCASE # for MKS sh + + # Support unset when possible. + if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset + else + as_unset=false + fi + + + # Work around bugs in pre-3.0 UWIN ksh. + $as_unset ENV MAIL MAILPATH + PS1='$ ' + PS2='> ' + PS4='+ ' + + # NLS nuisances. + for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME + do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi + done + + # Required to use basename. + if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr + else + as_expr=false + fi + + if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename + else + as_basename=false + fi + + + # Name of the executable. + as_me=`$as_basename "$0" || + $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || + echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + + # PATH needs CR, and LINENO needs CR and PATH. + # Avoid depending upon Character Ranges. + as_cr_letters='abcdefghijklmnopqrstuvwxyz' + as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' + as_cr_Letters=$as_cr_letters$as_cr_LETTERS + as_cr_digits='0123456789' + as_cr_alnum=$as_cr_Letters$as_cr_digits + + # The user is always right. + if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh + fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR + for as_dir in $PATH + do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR + for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH + do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done + done + ;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit + } + + + case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' + ' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; + esac + + if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr + else + as_expr=false + fi + + rm -f conf$$ conf$$.exe conf$$.file + echo >conf$$.file + if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi + rm -f conf$$ conf$$.exe conf$$.file + + if mkdir -p . 2>/dev/null; then + as_mkdir_p=: + else + test -d ./-p && rmdir ./-p + as_mkdir_p=false + fi + + as_executable_p="test -f" + + # Sed expression to map a string onto a valid CPP name. + as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + + # Sed expression to map a string onto a valid variable name. + as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + # IFS + # We need space, tab and new line, in precisely that order. + as_nl=' + ' + IFS=" $as_nl" + + # CDPATH. + $as_unset CDPATH + + + # Name of the host. + # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, + # so uname gets run too. + ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + + exec 6>&1 + + # + # Initializations. + # + ac_default_prefix=/usr/local + ac_config_libobj_dir=. + cross_compiling=no + subdirs= + MFLAGS= + MAKEFLAGS= + SHELL=${CONFIG_SHELL-/bin/sh} + + # Maximum number of lines to put in a shell here document. + # This variable seems obsolete. It should probably be removed, and + # only ac_max_sed_lines should be used. + : ${ac_max_here_lines=38} + + # Identity of this package. + PACKAGE_NAME='[ModuleMaker]' + PACKAGE_TARNAME='--modulemaker--' + PACKAGE_VERSION='[x.xx]' + PACKAGE_STRING='[ModuleMaker] [x.xx]' + PACKAGE_BUGREPORT='bugs at yourdomain' + + ac_unique_file=""Makefile.common.in"" + ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS LLVM_SRC LLVM_OBJ LIBOBJS LTLIBOBJS' + ac_subst_files='' + + # Initialize some variables set by options. + ac_init_help= + ac_init_version=false + # The variables have the same names as the options, with + # dashes changed to underlines. + cache_file=/dev/null + exec_prefix=NONE + no_create= + no_recursion= + prefix=NONE + program_prefix=NONE + program_suffix=NONE + program_transform_name=s,x,x, + silent= + site= + srcdir= + verbose= + x_includes=NONE + x_libraries=NONE + + # Installation directory options. + # These are left unexpanded so users can "make install exec_prefix=/foo" + # and all the variables that are supposed to be based on exec_prefix + # by default will actually change. + # Use braces instead of parens because sh, perl, etc. also accept them. + bindir='${exec_prefix}/bin' + sbindir='${exec_prefix}/sbin' + libexecdir='${exec_prefix}/libexec' + datadir='${prefix}/share' + sysconfdir='${prefix}/etc' + sharedstatedir='${prefix}/com' + localstatedir='${prefix}/var' + libdir='${exec_prefix}/lib' + includedir='${prefix}/include' + oldincludedir='/usr/include' + infodir='${prefix}/info' + mandir='${prefix}/man' + + ac_prev= + for ac_option + do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option + Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac + done + + if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } + fi + + # Be sure to have absolute paths. + for ac_var in exec_prefix prefix + do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac + done + + # Be sure to have absolute paths. + for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir + do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac + done + + # There might be people who depend on the old broken behavior: `$host' + # used to hold the argument of --host etc. + # FIXME: To remove some day. + build=$build_alias + host=$host_alias + target=$target_alias + + # FIXME: To remove some day. + if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi + fi + + ac_tool_prefix= + test -n "$host_alias" && ac_tool_prefix=$host_alias- + + test "$silent" = yes && exec 6>/dev/null + + + # Find the source files, if location was not specified. + if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || + $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || + echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi + else + ac_srcdir_defaulted=no + fi + if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi + fi + (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } + srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` + ac_env_build_alias_set=${build_alias+set} + ac_env_build_alias_value=$build_alias + ac_cv_env_build_alias_set=${build_alias+set} + ac_cv_env_build_alias_value=$build_alias + ac_env_host_alias_set=${host_alias+set} + ac_env_host_alias_value=$host_alias + ac_cv_env_host_alias_set=${host_alias+set} + ac_cv_env_host_alias_value=$host_alias + ac_env_target_alias_set=${target_alias+set} + ac_env_target_alias_value=$target_alias + ac_cv_env_target_alias_set=${target_alias+set} + ac_cv_env_target_alias_value=$target_alias + + # + # Report the --help message. + # + if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF + \`configure' configures [ModuleMaker] [x.xx] to adapt to many kinds of systems. + + Usage: $0 [OPTION]... [VAR=VALUE]... + + To assign environment variables (e.g., CC, CFLAGS...), specify them as + VAR=VALUE. See below for descriptions of some of the useful variables. + + Defaults for the options are specified in brackets. + + Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + + _ACEOF + + cat <<_ACEOF + Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + + By default, \`make install' will install all the files in + \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify + an installation prefix other than \`$ac_default_prefix' using \`--prefix', + for instance \`--prefix=\$HOME'. + + For better control, use the options below. + + Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] + _ACEOF + + cat <<\_ACEOF + _ACEOF + fi + + if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of [ModuleMaker] [x.xx]:";; + esac + cat <<\_ACEOF + + Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-llvmsrc Location of LLVM Source Code + --with-llvmobj Location of LLVM Object Code + + Report bugs to . + _ACEOF + fi + + if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + + if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` + else + ac_dir_suffix= ac_top_builddir= + fi + + case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; + esac + case "$ac_dir" in + .) ac_abs_builddir=$ac_builddir;; + *) + case $ac_builddir in + .) ac_abs_builddir="$ac_dir";; + [\\/]* | ?:[\\/]* ) ac_abs_builddir=$ac_builddir;; + *) ac_abs_builddir="$ac_dir"/$ac_builddir;; + esac;; + esac + case "$ac_dir" in + .) ac_abs_top_builddir=${ac_top_builddir}.;; + *) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir="$ac_dir";; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir="$ac_dir"/${ac_top_builddir}.;; + esac;; + esac + case "$ac_dir" in + .) ac_abs_srcdir=$ac_srcdir;; + *) + case $ac_srcdir in + .) ac_abs_srcdir="$ac_dir";; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir="$ac_dir"/$ac_srcdir;; + esac;; + esac + case "$ac_dir" in + .) ac_abs_top_srcdir=$ac_top_srcdir;; + *) + case $ac_top_srcdir in + .) ac_abs_top_srcdir="$ac_dir";; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir="$ac_dir"/$ac_top_srcdir;; + esac;; + esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done + fi + + test -n "$ac_init_help" && exit 0 + if $ac_init_version; then + cat <<\_ACEOF + [ModuleMaker] configure [x.xx] + generated by GNU Autoconf 2.58 + + Copyright (C) 2003 Free Software Foundation, Inc. + This configure script is free software; the Free Software Foundation + gives unlimited permission to copy, distribute and modify it. + _ACEOF + exit 0 + fi + exec 5>config.log + cat >&5 <<_ACEOF + This file contains any messages produced by compilers while + running configure, to aid debugging if configure makes a mistake. + + It was created by [ModuleMaker] $as_me [x.xx], which was + generated by GNU Autoconf 2.58. Invocation command line was + + $ $0 $@ + + _ACEOF + { + cat <<_ASUNAME + ## --------- ## + ## Platform. ## + ## --------- ## + + hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` + uname -m = `(uname -m) 2>/dev/null || echo unknown` + uname -r = `(uname -r) 2>/dev/null || echo unknown` + uname -s = `(uname -s) 2>/dev/null || echo unknown` + uname -v = `(uname -v) 2>/dev/null || echo unknown` + + /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` + /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + + /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` + /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` + /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` + hostinfo = `(hostinfo) 2>/dev/null || echo unknown` + /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` + /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` + /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + + _ASUNAME + + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR + for as_dir in $PATH + do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" + done + + } >&5 + + cat >&5 <<_ACEOF + + + ## ----------- ## + ## Core tests. ## + ## ----------- ## + + _ACEOF + + + # Keep a trace of the command line. + # Strip out --no-create and --no-recursion so they do not pile up. + # Strip out --silent because we don't want to record it for future runs. + # Also quote any args containing shell meta-characters. + # Make two passes to allow for proper duplicate-argument suppression. + ac_configure_args= + ac_configure_args0= + ac_configure_args1= + ac_sep= + ac_must_keep_next=false + for ac_pass in 1 2 + do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done + done + $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } + $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + + # When interrupted or exit'd, cleanup temporary files, and complete + # config.log. We remove comments because anyway the quotes in there + # would cause problems or look ugly. + # WARNING: Be sure not to use single quotes in there, as some shells, + # such as our DU 5.0 friend, will then `close' the trap. + trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX + ## ---------------- ## + ## Cache variables. ## + ## ---------------- ## + _ASBOX + echo + # The following way of writing the cache mishandles newlines in values, + { + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; + } + echo + + cat <<\_ASBOX + ## ----------------- ## + ## Output variables. ## + ## ----------------- ## + _ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX + ## ------------- ## + ## Output files. ## + ## ------------- ## + _ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX + ## ----------- ## + ## confdefs.h. ## + ## ----------- ## + _ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 + for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal + done + ac_signal=0 + + # confdefs.h avoids OS command line length limits that DEFS can exceed. + rm -rf conftest* confdefs.h + # AIX cpp loses on an empty file, so make sure it contains at least a newline. + echo >confdefs.h + + # Predefined preprocessor variables. + + cat >>confdefs.h <<_ACEOF + #define PACKAGE_NAME "$PACKAGE_NAME" + _ACEOF + + + cat >>confdefs.h <<_ACEOF + #define PACKAGE_TARNAME "$PACKAGE_TARNAME" + _ACEOF + + + cat >>confdefs.h <<_ACEOF + #define PACKAGE_VERSION "$PACKAGE_VERSION" + _ACEOF + + + cat >>confdefs.h <<_ACEOF + #define PACKAGE_STRING "$PACKAGE_STRING" + _ACEOF + + + cat >>confdefs.h <<_ACEOF + #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" + _ACEOF + + + # Let the site file select an alternate cache file if it wants to. + # Prefer explicitly selected file to automatically selected ones. + if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi + fi + for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 + echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi + done + + if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 + echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi + else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 + echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file + fi + + # Check that the precious variables saved in the cache have kept the same + # value. + ac_cache_corrupted=false + for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 + echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 + echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 + echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 + echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 + echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi + done + if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 + echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 + echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } + fi + + ac_ext=c + ac_cpp='$CPP $CPPFLAGS' + ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' + ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' + ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ac_aux_dir= + for ac_dir in autoconf $srcdir/autoconf; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi + done + if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in autoconf $srcdir/autoconf" >&5 + echo "$as_me: error: cannot find install-sh or install.sh in autoconf $srcdir/autoconf" >&2;} + { (exit 1); exit 1; }; } + fi + ac_config_guess="$SHELL $ac_aux_dir/config.guess" + ac_config_sub="$SHELL $ac_aux_dir/config.sub" + ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + + + + + ac_config_commands="$ac_config_commands Makefile" + + + ac_config_commands="$ac_config_commands lib/Makefile" + + + ac_config_commands="$ac_config_commands lib/ClassFile/Makefile" + + + ac_config_commands="$ac_config_commands tools/Makefile" + + + ac_config_commands="$ac_config_commands tools/classdump/Makefile" + + + + + + + + + + + + + + + # Check whether --with-llvmsrc or --without-llvmsrc was given. + if test "${with_llvmsrc+set}" = set; then + withval="$with_llvmsrc" + LLVM_SRC=$withval + + else + LLVM_SRC=`cd ${srcdir}/../..; pwd` + + fi; + + + # Check whether --with-llvmobj or --without-llvmobj was given. + if test "${with_llvmobj+set}" = set; then + withval="$with_llvmobj" + LLVM_OBJ=$withval + + else + LLVM_OBJ=`cd ../..; pwd` + + fi; + + ac_config_files="$ac_config_files Makefile.common" + cat >confcache <<\_ACEOF + # This file is a shell script that caches the results of configure + # tests run on this system so they can be shared between configure + # scripts and configure runs, see configure's option --config-cache. + # It is not useful on other systems. If it contains results you don't + # want to keep, you may remove or edit it. + # + # config.status only pays attention to the cache file if you give it + # the --recheck option to rerun configure. + # + # `ac_cv_env_foo' variables (set or unset) will be overridden when + # loading this file, other *unset* `ac_cv_foo' will be assigned the + # following values. + + _ACEOF + + # The following way of writing the cache mishandles newlines in values, + # but we know of no workaround that is simple, portable, and efficient. + # So, don't put newlines in cache variables' values. + # Ultrix sh set writes to stderr and can't be redirected directly, + # and sets the high bit in the cache file unless we assign to the vars. + { + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; + } | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache + if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi + fi + rm -f confcache + + test "x$prefix" = xNONE && prefix=$ac_default_prefix + # Let make expand exec_prefix. + test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + + # VPATH may cause trouble with some makes, so we remove $(srcdir), + # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and + # trailing colons and then remove the whole line if VPATH becomes empty + # (actually we leave an empty line to preserve line numbers). + if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ + s/:*\$(srcdir):*/:/; + s/:*\${srcdir}:*/:/; + s/:*@srcdir@:*/:/; + s/^\([^=]*=[ ]*\):*/\1/; + s/:*$//; + s/^[^=]*=[ ]*$//; + }' + fi + + # Transform confdefs.h into DEFS. + # Protect against shell expansion while executing Makefile rules. + # Protect against Makefile macro expansion. + # + # If the first sed substitution is executed (which looks for macros that + # take arguments), then we branch to the quote section. Otherwise, + # look for a macro that doesn't take arguments. + cat >confdef2opt.sed <<\_ACEOF + t clear + : clear + s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g + t quote + s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g + t quote + d + : quote + s,[ `~#$^&*(){}\\|;'"<>?],\\&,g + s,\[,\\&,g + s,\],\\&,g + s,\$,$$,g + p + _ACEOF + # We use echo to avoid assuming a particular line-breaking character. + # The extra dot is to prevent the shell from consuming trailing + # line-breaks from the sub-command output. A line-break within + # single-quotes doesn't work because, if this script is created in a + # platform that uses two characters for line-breaks (e.g., DOS), tr + # would break. + ac_LF_and_DOT=`echo; echo .` + DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` + rm -f confdef2opt.sed + + + ac_libobjs= + ac_ltlibobjs= + for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' + done + LIBOBJS=$ac_libobjs + + LTLIBOBJS=$ac_ltlibobjs + + + + : ${CONFIG_STATUS=./config.status} + ac_clean_files_save=$ac_clean_files + ac_clean_files="$ac_clean_files $CONFIG_STATUS" + { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 + echo "$as_me: creating $CONFIG_STATUS" >&6;} + cat >$CONFIG_STATUS <<_ACEOF + #! $SHELL + # Generated by $as_me. + # Run this file to recreate the current configuration. + # Compiler output produced by configure, useful for debugging + # configure, is in config.log if it exists. + + debug=false + ac_cs_recheck=false + ac_cs_silent=false + SHELL=\${CONFIG_SHELL-$SHELL} + _ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + ## --------------------- ## + ## M4sh Initialization. ## + ## --------------------- ## + + # Be Bourne compatible + if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix + fi + DUALCASE=1; export DUALCASE # for MKS sh + + # Support unset when possible. + if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset + else + as_unset=false + fi + + + # Work around bugs in pre-3.0 UWIN ksh. + $as_unset ENV MAIL MAILPATH + PS1='$ ' + PS2='> ' + PS4='+ ' + + # NLS nuisances. + for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME + do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi + done + + # Required to use basename. + if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr + else + as_expr=false + fi + + if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename + else + as_basename=false + fi + + + # Name of the executable. + as_me=`$as_basename "$0" || + $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || + echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + + # PATH needs CR, and LINENO needs CR and PATH. + # Avoid depending upon Character Ranges. + as_cr_letters='abcdefghijklmnopqrstuvwxyz' + as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' + as_cr_Letters=$as_cr_letters$as_cr_LETTERS + as_cr_digits='0123456789' + as_cr_alnum=$as_cr_Letters$as_cr_digits + + # The user is always right. + if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh + fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR + for as_dir in $PATH + do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 + echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR + for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH + do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done + done + ;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 + echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit + } + + + case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' + ' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; + esac + + if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr + else + as_expr=false + fi + + rm -f conf$$ conf$$.exe conf$$.file + echo >conf$$.file + if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi + rm -f conf$$ conf$$.exe conf$$.file + + if mkdir -p . 2>/dev/null; then + as_mkdir_p=: + else + test -d ./-p && rmdir ./-p + as_mkdir_p=false + fi + + as_executable_p="test -f" + + # Sed expression to map a string onto a valid CPP name. + as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + + # Sed expression to map a string onto a valid variable name. + as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + # IFS + # We need space, tab and new line, in precisely that order. + as_nl=' + ' + IFS=" $as_nl" + + # CDPATH. + $as_unset CDPATH + + exec 6>&1 + + # Open the log real soon, to keep \$[0] and so on meaningful, and to + # report actual input values of CONFIG_FILES etc. instead of their + # values after options handling. Logging --version etc. is OK. + exec 5>>config.log + { + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX + ## Running $as_me. ## + _ASBOX + } >&5 + cat >&5 <<_CSEOF + + This file was extended by [ModuleMaker] $as_me [x.xx], which was + generated by GNU Autoconf 2.58. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + + _CSEOF + echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 + echo >&5 + _ACEOF + + # Files that config.status was made for. + if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS + fi + + if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS + fi + + if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS + fi + + if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS + fi + + cat >>$CONFIG_STATUS <<\_ACEOF + + ac_cs_usage="\ + \`$as_me' instantiates files from templates according to the + current configuration. + + Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + + Configuration files: + $config_files + + Configuration commands: + $config_commands + + Report bugs to ." + _ACEOF + + cat >>$CONFIG_STATUS <<_ACEOF + ac_cs_version="\\ + [ModuleMaker] config.status [x.xx] + configured by $0, generated by GNU Autoconf 2.58, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + + Copyright (C) 2003 Free Software Foundation, Inc. + This config.status script is free software; the Free Software Foundation + gives unlimited permission to copy, distribute and modify it." + srcdir=$srcdir + _ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # If no file are specified by the user, then we need to provide default + # value. By we need to know if files were specified by the user. + ac_need_defaults=: + while test $# != 0 + do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. + _ACEOF + cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 + Try \`$0 --help' for more information." >&5 + echo "$as_me: error: ambiguous option: $1 + Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 + Try \`$0 --help' for more information." >&5 + echo "$as_me: error: unrecognized option: $1 + Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift + done + + ac_configure_extra_args= + + if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" + fi + + _ACEOF + cat >>$CONFIG_STATUS <<_ACEOF + if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + fi + + _ACEOF + + cat >>$CONFIG_STATUS <<_ACEOF + # + # INIT-COMMANDS section. + # + + ${srcdir}/autoconf/mkinstalldirs `dirname Makefile` + ${srcdir}/autoconf/mkinstalldirs `dirname lib/Makefile` + ${srcdir}/autoconf/mkinstalldirs `dirname lib/ClassFile/Makefile` + ${srcdir}/autoconf/mkinstalldirs `dirname tools/Makefile` + ${srcdir}/autoconf/mkinstalldirs `dirname tools/classdump/Makefile` + + _ACEOF + + + + cat >>$CONFIG_STATUS <<\_ACEOF + for ac_config_target in $ac_config_targets + do + case "$ac_config_target" in + # Handling of arguments. + "Makefile.common" ) CONFIG_FILES="$CONFIG_FILES Makefile.common" ;; + "Makefile" ) CONFIG_COMMANDS="$CONFIG_COMMANDS Makefile" ;; + "lib/Makefile" ) CONFIG_COMMANDS="$CONFIG_COMMANDS lib/Makefile" ;; + "lib/ClassFile/Makefile" ) CONFIG_COMMANDS="$CONFIG_COMMANDS lib/ClassFile/Makefile" ;; + "tools/Makefile" ) CONFIG_COMMANDS="$CONFIG_COMMANDS tools/Makefile" ;; + "tools/classdump/Makefile" ) CONFIG_COMMANDS="$CONFIG_COMMANDS tools/classdump/Makefile" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 + echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac + done + + # If the user did not use the arguments to specify the items to instantiate, + # then the envvar interface is used. Set only those that are not. + # We use the long form for the default assignment because of an extremely + # bizarre bug on SunOS 4.1.3. + if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands + fi + + # Have a temporary directory for convenience. Make it in the build tree + # simply because there is no reason to put it here, and in addition, + # creating and moving files from /tmp can sometimes cause problems. + # Create a temporary directory, and hook for its removal unless debugging. + $debug || + { + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 + } + + # Create a (secure) tmp directory for tmp files. + + { + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" + } || + { + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) + } || + { + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } + } + + _ACEOF + + cat >>$CONFIG_STATUS <<_ACEOF + + # + # CONFIG_FILES section. + # + + # No need to generate the scripts if there are no CONFIG_FILES. + # This happens for instance when ./config.status config.h + if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF + s, at SHELL@,$SHELL,;t t + s, at PATH_SEPARATOR@,$PATH_SEPARATOR,;t t + s, at PACKAGE_NAME@,$PACKAGE_NAME,;t t + s, at PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t + s, at PACKAGE_VERSION@,$PACKAGE_VERSION,;t t + s, at PACKAGE_STRING@,$PACKAGE_STRING,;t t + s, at PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t + s, at exec_prefix@,$exec_prefix,;t t + s, at prefix@,$prefix,;t t + s, at program_transform_name@,$program_transform_name,;t t + s, at bindir@,$bindir,;t t + s, at sbindir@,$sbindir,;t t + s, at libexecdir@,$libexecdir,;t t + s, at datadir@,$datadir,;t t + s, at sysconfdir@,$sysconfdir,;t t + s, at sharedstatedir@,$sharedstatedir,;t t + s, at localstatedir@,$localstatedir,;t t + s, at libdir@,$libdir,;t t + s, at includedir@,$includedir,;t t + s, at oldincludedir@,$oldincludedir,;t t + s, at infodir@,$infodir,;t t + s, at mandir@,$mandir,;t t + s, at build_alias@,$build_alias,;t t + s, at host_alias@,$host_alias,;t t + s, at target_alias@,$target_alias,;t t + s, at DEFS@,$DEFS,;t t + s, at ECHO_C@,$ECHO_C,;t t + s, at ECHO_N@,$ECHO_N,;t t + s, at ECHO_T@,$ECHO_T,;t t + s, at LIBS@,$LIBS,;t t + s, at LLVM_SRC@,$LLVM_SRC,;t t + s, at LLVM_OBJ@,$LLVM_OBJ,;t t + s, at LIBOBJS@,$LIBOBJS,;t t + s, at LTLIBOBJS@,$LTLIBOBJS,;t t + CEOF + + _ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi + fi # test -n "$CONFIG_FILES" + + _ACEOF + cat >>$CONFIG_STATUS <<\_ACEOF + for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || + $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || + echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || + $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || + echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 + echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + + if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` + else + ac_dir_suffix= ac_top_builddir= + fi + + case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; + esac + case "$ac_dir" in + .) ac_abs_builddir=$ac_builddir;; + *) + case $ac_builddir in + .) ac_abs_builddir="$ac_dir";; + [\\/]* | ?:[\\/]* ) ac_abs_builddir=$ac_builddir;; + *) ac_abs_builddir="$ac_dir"/$ac_builddir;; + esac;; + esac + case "$ac_dir" in + .) ac_abs_top_builddir=${ac_top_builddir}.;; + *) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir="$ac_dir";; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir="$ac_dir"/${ac_top_builddir}.;; + esac;; + esac + case "$ac_dir" in + .) ac_abs_srcdir=$ac_srcdir;; + *) + case $ac_srcdir in + .) ac_abs_srcdir="$ac_dir";; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir="$ac_dir"/$ac_srcdir;; + esac;; + esac + case "$ac_dir" in + .) ac_abs_top_srcdir=$ac_top_srcdir;; + *) + case $ac_top_srcdir in + .) ac_abs_top_srcdir="$ac_dir";; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir="$ac_dir"/$ac_top_srcdir;; + esac;; + esac + + + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 + echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 + echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 + echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + _ACEOF + cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub + $extrasub + _ACEOF + cat >>$CONFIG_STATUS <<\_ACEOF + :t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b + s, at configure_input@,$configure_input,;t t + s, at srcdir@,$ac_srcdir,;t t + s, at abs_srcdir@,$ac_abs_srcdir,;t t + s, at top_srcdir@,$ac_top_srcdir,;t t + s, at abs_top_srcdir@,$ac_abs_top_srcdir,;t t + s, at builddir@,$ac_builddir,;t t + s, at abs_builddir@,$ac_abs_builddir,;t t + s, at top_builddir@,$ac_top_builddir,;t t + s, at abs_top_builddir@,$ac_abs_top_builddir,;t t + " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + + done + _ACEOF + cat >>$CONFIG_STATUS <<\_ACEOF + + # + # CONFIG_COMMANDS section. + # + for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue + ac_dest=`echo "$ac_file" | sed 's,:.*,,'` + ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_dir=`(dirname "$ac_dest") 2>/dev/null || + $as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_dest" : 'X\(//\)[^/]' \| \ + X"$ac_dest" : 'X\(//\)$' \| \ + X"$ac_dest" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || + echo X"$ac_dest" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || + $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || + echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 + echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + + if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` + else + ac_dir_suffix= ac_top_builddir= + fi + + case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; + esac + case "$ac_dir" in + .) ac_abs_builddir=$ac_builddir;; + *) + case $ac_builddir in + .) ac_abs_builddir="$ac_dir";; + [\\/]* | ?:[\\/]* ) ac_abs_builddir=$ac_builddir;; + *) ac_abs_builddir="$ac_dir"/$ac_builddir;; + esac;; + esac + case "$ac_dir" in + .) ac_abs_top_builddir=${ac_top_builddir}.;; + *) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir="$ac_dir";; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir="$ac_dir"/${ac_top_builddir}.;; + esac;; + esac + case "$ac_dir" in + .) ac_abs_srcdir=$ac_srcdir;; + *) + case $ac_srcdir in + .) ac_abs_srcdir="$ac_dir";; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir="$ac_dir"/$ac_srcdir;; + esac;; + esac + case "$ac_dir" in + .) ac_abs_top_srcdir=$ac_top_srcdir;; + *) + case $ac_top_srcdir in + .) ac_abs_top_srcdir="$ac_dir";; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir="$ac_dir"/$ac_top_srcdir;; + esac;; + esac + + + { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 + echo "$as_me: executing $ac_dest commands" >&6;} + case $ac_dest in + Makefile ) ${SHELL} ${srcdir}/autoconf/install-sh -c ${srcdir}/Makefile Makefile ;; + lib/Makefile ) ${SHELL} ${srcdir}/autoconf/install-sh -c ${srcdir}/lib/Makefile lib/Makefile ;; + lib/ClassFile/Makefile ) ${SHELL} ${srcdir}/autoconf/install-sh -c ${srcdir}/lib/ClassFile/Makefile lib/ClassFile/Makefile ;; + tools/Makefile ) ${SHELL} ${srcdir}/autoconf/install-sh -c ${srcdir}/tools/Makefile tools/Makefile ;; + tools/classdump/Makefile ) ${SHELL} ${srcdir}/autoconf/install-sh -c ${srcdir}/tools/classdump/Makefile tools/classdump/Makefile ;; + esac + done + _ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + + { (exit 0); exit 0; } + _ACEOF + chmod +x $CONFIG_STATUS + ac_clean_files=$ac_clean_files_save + + + # configure is writing to config.log, and then calls config.status. + # config.status does its own redirection, appending to config.log. + # Unfortunately, on DOS this fails, as config.log is still kept open + # by configure, so config.status won't be able to write to it; its + # output is simply discarded. So we exec the FD to /dev/null, + # effectively closing config.log, so it can be properly (re)opened and + # appended to by config.status. When coming back to configure, we + # need to make the FD available again. + if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } + fi + From alkis at cs.uiuc.edu Thu Apr 15 16:01:42 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 16:01:42 2004 Subject: [llvm-commits] CVS: llvm-java/autoconf/Makefile configure.ac install-sh ltmain.sh mkinstalldirs Message-ID: <200404152101.QAA10571@zion.cs.uiuc.edu> Changes in directory llvm-java/autoconf: Makefile added (r1.1) configure.ac added (r1.1) install-sh added (r1.1) ltmain.sh added (r1.1) mkinstalldirs added (r1.1) --- Log message: Initial checking of the llvm java-frontend. This contains a skeleton and a preliminary ClassFile parsing library --- Diffs of the changes: (+5594 -0) Index: llvm-java/autoconf/Makefile diff -c /dev/null llvm-java/autoconf/Makefile:1.1 *** /dev/null Thu Apr 15 16:00:59 2004 --- llvm-java/autoconf/Makefile Thu Apr 15 16:00:49 2004 *************** *** 0 **** --- 1,3 ---- + all: + aclocal -I ../../../autoconf + autoconf-2.58 -o ../configure Index: llvm-java/autoconf/configure.ac diff -c /dev/null llvm-java/autoconf/configure.ac:1.1 *** /dev/null Thu Apr 15 16:00:59 2004 --- llvm-java/autoconf/configure.ac Thu Apr 15 16:00:49 2004 *************** *** 0 **** --- 1,70 ---- + dnl ************************************************************************** + dnl * Initialize + dnl ************************************************************************** + AC_INIT([[[ModuleMaker]]],[[[x.xx]]],[bugs at yourdomain]) + + dnl Place all of the extra autoconf files into the config subdirectory + AC_CONFIG_AUX_DIR([autoconf]) + + dnl Configure a header file + + dnl Configure Makefiles + dnl List every Makefile that exists within your source tree + + AC_CONFIG_MAKEFILE(Makefile) + AC_CONFIG_MAKEFILE(lib/Makefile) + AC_CONFIG_MAKEFILE(lib/ClassFile/Makefile) + AC_CONFIG_MAKEFILE(tools/Makefile) + AC_CONFIG_MAKEFILE(tools/classdump/Makefile) + + dnl ************************************************************************** + dnl * Determine which system we are building on + dnl ************************************************************************** + + dnl ************************************************************************** + dnl * Check for programs. + dnl ************************************************************************** + + dnl Verify that the source directory is valid + AC_CONFIG_SRCDIR(["Makefile.common.in"]) + + dnl ************************************************************************** + dnl * Check for libraries. + dnl ************************************************************************** + + dnl ************************************************************************** + dnl * Checks for header files. + dnl ************************************************************************** + + dnl ************************************************************************** + dnl * Checks for typedefs, structures, and compiler characteristics. + dnl ************************************************************************** + + dnl ************************************************************************** + dnl * Checks for library functions. + dnl ************************************************************************** + + dnl ************************************************************************** + dnl * Enable various compile-time options + dnl ************************************************************************** + + dnl ************************************************************************** + dnl * Set the location of various third-party software packages + dnl ************************************************************************** + + dnl Location of LLVM source code + AC_ARG_WITH(llvmsrc, + AC_HELP_STRING([--with-llvmsrc],[Location of LLVM Source Code]), + AC_SUBST(LLVM_SRC,[$withval]), + AC_SUBST(LLVM_SRC,[`cd ${srcdir}/../..; pwd`])) + + dnl Location of LLVM object code + AC_ARG_WITH(llvmobj, + AC_HELP_STRING([--with-llvmobj],[Location of LLVM Object Code]), + AC_SUBST(LLVM_OBJ,[$withval]), + AC_SUBST(LLVM_OBJ,[`cd ../..; pwd`])) + + dnl ************************************************************************** + dnl * Create the output files + dnl ************************************************************************** + AC_OUTPUT(Makefile.common) Index: llvm-java/autoconf/install-sh diff -c /dev/null llvm-java/autoconf/install-sh:1.1 *** /dev/null Thu Apr 15 16:01:00 2004 --- llvm-java/autoconf/install-sh Thu Apr 15 16:00:49 2004 *************** *** 0 **** --- 1,251 ---- + #!/bin/sh + # + # install - install a program, script, or datafile + # This comes from X11R5 (mit/util/scripts/install.sh). + # + # Copyright 1991 by the Massachusetts Institute of Technology + # + # Permission to use, copy, modify, distribute, and sell this software and its + # documentation for any purpose is hereby granted without fee, provided that + # the above copyright notice appear in all copies and that both that + # copyright notice and this permission notice appear in supporting + # documentation, and that the name of M.I.T. not be used in advertising or + # publicity pertaining to distribution of the software without specific, + # written prior permission. M.I.T. makes no representations about the + # suitability of this software for any purpose. It is provided "as is" + # without express or implied warranty. + # + # Calling this script install-sh is preferred over install.sh, to prevent + # `make' implicit rules from creating a file called install from it + # when there is no Makefile. + # + # This script is compatible with the BSD install script, but was written + # from scratch. It can only install one file at a time, a restriction + # shared with many OS's install programs. + + + # set DOITPROG to echo to test this script + + # Don't use :- since 4.3BSD and earlier shells don't like it. + doit="${DOITPROG-}" + + + # put in absolute paths if you don't have them in your path; or use env. vars. + + mvprog="${MVPROG-mv}" + cpprog="${CPPROG-cp}" + chmodprog="${CHMODPROG-chmod}" + chownprog="${CHOWNPROG-chown}" + chgrpprog="${CHGRPPROG-chgrp}" + stripprog="${STRIPPROG-strip}" + rmprog="${RMPROG-rm}" + mkdirprog="${MKDIRPROG-mkdir}" + + transformbasename="" + transform_arg="" + instcmd="$mvprog" + chmodcmd="$chmodprog 0755" + chowncmd="" + chgrpcmd="" + stripcmd="" + rmcmd="$rmprog -f" + mvcmd="$mvprog" + src="" + dst="" + dir_arg="" + + while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac + done + + if [ x"$src" = x ] + then + echo "install: no input file specified" + exit 1 + else + : + fi + + if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=$mkdirprog + fi + else + + # Waiting for this to be detected by the "$instcmd $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + : + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + : + fi + + # If destination is a directory, append the input filename; if your system + # does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + : + fi + fi + + ## this sed command emulates the dirname command + dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + # this part is taken from Noah Friedman's mkinstalldirs script + + # Skip lots of stat calls in the usual case. + if [ ! -d "$dstdir" ]; then + defaultIFS=' + ' + IFS="${IFS-${defaultIFS}}" + + oIFS="${IFS}" + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` + IFS="${oIFS}" + + pathcomp='' + + while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + : + fi + + pathcomp="${pathcomp}/" + done + fi + + if [ x"$dir_arg" != x ] + then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi + else + + # If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + + # don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + : + fi + + # Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + + # Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + + # and set any options; do chmod last to preserve setuid bits + + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi && + + # Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + + fi && + + + exit 0 Index: llvm-java/autoconf/ltmain.sh diff -c /dev/null llvm-java/autoconf/ltmain.sh:1.1 *** /dev/null Thu Apr 15 16:01:00 2004 --- llvm-java/autoconf/ltmain.sh Thu Apr 15 16:00:49 2004 *************** *** 0 **** --- 1,5169 ---- + # ltmain.sh - Provide generalized library-building support services. + # NOTE: Changing this file will not affect anything until you rerun configure. + # + # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 + # Free Software Foundation, Inc. + # Originally by Gordon Matzigkeit , 1996 + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 2 of the License, or + # (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, but + # WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + # General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with this program; if not, write to the Free Software + # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + # + # As a special exception to the GNU General Public License, if you + # distribute this file as part of a program that contains a + # configuration script generated by Autoconf, you may include it under + # the same distribution terms that you use for the rest of that program. + + # Check that we have a working $echo. + if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : + elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : + else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$0" --no-reexec ${1+"$@"} + fi + + if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 + fi + + # Global variables. + mode=$default_mode + nonopt= + prev= + prevopt= + run= + show="$echo" + show_help= + execute_dlfiles= + lo2o="s/\\.lo\$/.${objext}/" + o2lo="s/\\.${objext}\$/.lo/" + + # Parse our command line options once, thoroughly. + while test $# -gt 0 + do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + exit 0 + ;; + + --config) + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0 + exit 0 + ;; + + --debug) + echo "$progname: enabling shell trace mode" + set -x + ;; + + --dry-run | -n) + run=: + ;; + + --features) + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + exit 0 + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --quiet | --silent) + show=: + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *) + nonopt="$arg" + break + ;; + esac + done + + if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # If this variable is set in any of the actions, the command in it + # will be execed at the end. This prevents here-documents from being + # left over by shells. + exec_cmd= + + if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + case $nonopt in + *cc | *++ | gcc* | *-gcc* | xlc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + prev= + lastarg= + srcfile="$nonopt" + suppress_output= + + user_target=no + for arg + do + case $prev in + "") ;; + xcompiler) + # Aesthetically quote the previous argument. + prev= + lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + + case $arg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + continue + ;; + esac + + # Accept any command-line options. + case $arg in + -o) + if test "$user_target" != "no"; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit 1 + fi + user_target=next + ;; + + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + continue + ;; + esac + + case $user_target in + next) + # The next one is the -o target name + user_target=yes + continue + ;; + yes) + # We got the output file + user_target=set + libobj="$arg" + continue + ;; + esac + + # Accept the current argument as the source file. + lastarg="$srcfile" + srcfile="$arg" + + # Aesthetically quote the previous argument. + + # Backslashify any backslashes, double quotes, and dollar signs. + # These are the only characters that are still specially + # interpreted inside of double-quoted scrings. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $lastarg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + done + + case $user_target in + set) + ;; + no) + # Get the name of the library object. + libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + *) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit 1 + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSfmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit 1 + ;; + esac + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $libobj" + else + removelist="$libobj" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit 1" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit 1" 1 2 15 + else + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $run ln "$0" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + echo "\ + *** ERROR, $lockfile exists and contains: + `cat $lockfile 2>/dev/null` + + This indicates that another process is trying to use the same + temporary object file, and libtool could not work around it because + your compiler does not support \`-c' and \`-o' together. If you + repeat this compilation, it may succeed, by chance, but you had better + avoid parallel builds (make -j) in this platform, or get a better + compiler." + + $run $rm $removelist + exit 1 + fi + echo $srcfile > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $srcfile $pic_flag -DPIC" + else + # Don't build PIC code + command="$base_compile $srcfile" + fi + if test "$build_old_libs" = yes; then + lo_libobj="$libobj" + dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$libobj"; then + dir="$objdir" + else + dir="$dir/$objdir" + fi + libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` + + if test -d "$dir"; then + $show "$rm $libobj" + $run $rm $libobj + else + $show "$mkdir $dir" + $run $mkdir $dir + status=$? + if test $status -ne 0 && test ! -d $dir; then + exit $status + fi + fi + fi + if test "$compiler_o_lo" = yes; then + output_obj="$libobj" + command="$command -o $output_obj" + elif test "$compiler_c_o" = yes; then + output_obj="$obj" + command="$command -o $output_obj" + fi + + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + test -n "$output_obj" && $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ + *** ERROR, $lockfile contains: + `cat $lockfile 2>/dev/null` + + but it should contain: + $srcfile + + This indicates that another process is trying to use the same + temporary object file, and libtool could not work around it because + your compiler does not support \`-c' and \`-o' together. If you + repeat this compilation, it may succeed, by chance, but you had better + avoid parallel builds (make -j) in this platform, or get a better + compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed, then go on to compile the next one + if test x"$output_obj" != x"$libobj"; then + $show "$mv $output_obj $libobj" + if $run $mv $output_obj $libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # If we have no pic_flag, then copy the object into place and finish. + if (test -z "$pic_flag" || test "$pic_mode" != default) && + test "$build_old_libs" = yes; then + # Rename the .lo from within objdir to obj + if test -f $obj; then + $show $rm $obj + $run $rm $obj + fi + + $show "$mv $libobj $obj" + if $run $mv $libobj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"` + libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` + # Now arrange that obj and lo_libobj become the same file + $show "(cd $xdir && $LN_S $baseobj $libobj)" + if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + $run $rm "$lockfile" + fi + exit 0 + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Allow error messages only from the first compilation. + suppress_output=' >/dev/null 2>&1' + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $srcfile" + else + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $srcfile $pic_flag -DPIC" + fi + if test "$compiler_c_o" = yes; then + command="$command -o $obj" + output_obj="$obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ + *** ERROR, $lockfile contains: + `cat $lockfile 2>/dev/null` + + but it should contain: + $srcfile + + This indicates that another process is trying to use the same + temporary object file, and libtool could not work around it because + your compiler does not support \`-c' and \`-o' together. If you + repeat this compilation, it may succeed, by chance, but you had better + avoid parallel builds (make -j) in this platform, or get a better + compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed + if test x"$output_obj" != x"$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Create an invalid libtool object if no PIC, so that we do not + # accidentally link it into a program. + if test "$build_libtool_libs" != yes; then + $show "echo timestamp > $libobj" + $run eval "echo timestamp > \$libobj" || exit $? + else + # Move the .lo from within objdir + $show "$mv $libobj $lo_libobj" + if $run $mv $libobj $lo_libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + fi + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + $run $rm "$lockfile" + fi + + exit 0 + ;; + + # libtool link mode + link | relink) + modename="$modename: link" + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invokation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args="$nonopt" + compile_command="$nonopt" + finalize_command="$nonopt" + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + + avoid_version=no + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -all-static | -static) + if test "X$arg" = "X-all-static"; then + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + else + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + fi + build_libtool_libs=no + build_old_libs=yes + prefer_static_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test $# -gt 0; do + arg="$1" + shift + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit 1 + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n $prev + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit 1 + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | no/*-*-nonstopux*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + exit 1 + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-mingw* | *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # The PATH hackery in wrapper scripts is required on Windows + # in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -o) prev=output ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -Kthread | -mthreads | -mt | -pthread | -pthreads | -threads | -qthreaded | -kthread ) + compiler_flags="$compiler_flags $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + + *.lo | *.$objext) + # A library or standard object. + if test "$prev" = dlfiles; then + # This file was specified with -dlopen. + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $arg" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"` + prev= + else + case $arg in + *.lo) libobjs="$libobjs $arg" ;; + *) objs="$objs $arg" ;; + esac + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d $output_objdir; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test $status -ne 0 && test ! -d $output_objdir; then + exit $status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit 1 + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test "$linkmode" = prog; then + # Determine which files to process + case $pass in + dlopen) + libs="$dlfiles" + save_deplibs="$deplibs" # Collect dlpreopened libraries + deplibs= + ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -l*) + if test "$linkmode" = oldlib && test "$linkmode" = obj; then + $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2 + continue + fi + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + # Search the libtool library + lib="$searchdir/lib${name}.la" + if test -f "$lib"; then + found=yes + break + fi + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + if test "$deplibs_check_method" != pass_all; then + echo + echo "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not used here." + else + echo + echo "*** Warning: Linking the shared library $output against the" + echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test "$found" = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib'" 1>&2 + exit 1 + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variable installed. + installed=yes + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" = oldlib && test "$linkmode" = obj; }; then + # Add dl[pre]opened files of deplib + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit 1 + fi + continue + fi # $pass = conv + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. + dlprefiles="$dlprefiles $lib" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" + fi + continue + fi + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + link_static=no # Whether the deplib will be linked statically + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + # Link against this shared library + + if test "$linkmode,$pass" = "prog,link" || + { test "$linkmode" = lib && test "$hardcode_into_libs" = yes; }; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + if test "$linkmode" = prog; then + # We need to hardcode the library path + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + fi + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + eval cmds=\"$extract_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + eval cmds=\"$old_archive_from_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n $old_archive_from_expsyms_cmds + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit 1 + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + # Try looking first in the location we're being installed to. + add_dir= + if test -n "$inst_prefix_dir"; then + case "$libdir" in + [\\/]*) + add_dir="-L$inst_prefix_dir$libdir" + ;; + esac + fi + add_dir="$add_dir -L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + else + # We cannot seem to hardcode it, guess we'll fake it. + # Try looking first in the location we're being installed to. + add_dir= + if test -n "$inst_prefix_dir"; then + case "$libdir" in + [\\/]*) + add_dir="-L$inst_prefix_dir$libdir" + ;; + esac + fi + add_dir="$add_dir -L$libdir" + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + + # Try to link the static library + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + echo "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + convenience="$convenience $dir/$old_library" + old_convenience="$old_convenience $dir/$old_library" + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="-L$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="-L$absdir" + fi + ;; + *) continue ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$deplibs $path" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + test "$pass" != scan && dependency_libs="$newdependency_libs" + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + *) + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + if test "$pass" = "conv" && + { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then + libs="$deplibs" # reset libs + deplibs= + fi + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit 1 + else + echo + echo "*** Warning: Linking the shared library $output against the non-libtool" + echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test $# -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + libext=al + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + current="$2" + revision="$3" + age="$4" + + # Check that each of the things are valid numbers. + case $current in + [0-9]*) ;; + *) + $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case $revision in + [0-9]*) ;; + *) + $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case $age in + [0-9]*) ;; + *) + $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + if test $age -gt $current; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + major=`expr $current - $age + 1` + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test $loop != 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=.`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test $loop != 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + verstring="0.0" + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring="" + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; then + # Remove our outputs. + $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*" + $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.* + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + for path in $notinst_path; do + lib_search_path=`echo "$lib_search_path " | ${SED} -e 's% $path % %g'` + deplibs=`echo "$deplibs " | ${SED} -e 's% -L$path % %g'` + dependency_libs=`echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` + done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behaviour. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + # It is ok to link against an archive when + # building a shared library. + if $AR -t $potlib > /dev/null 2>&1; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | ${SED} 10q \ + | egrep "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + echo "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + echo "*** with $libname but no candidates were found. (...for file magic test)" + else + echo "*** with $libname and none of the candidates passed a file format test" + echo "*** using a file magic. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name="`expr $a_deplib : '-l\(.*\)'`" + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check below in file_magic test + if eval echo \"$potent_lib\" 2>/dev/null \ + | ${SED} 10q \ + | egrep "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + echo "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + echo "*** with $libname but no candidates were found. (...for regex pattern test)" + else + echo "*** with $libname and none of the candidates passed a file format test" + echo "*** using a regex pattern. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' | + grep . >/dev/null; then + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + echo "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + test -z "$dlname" && dlname=$soname + + lib="$output_objdir/$realname" + for link + do + linknames="$linknames $link" + done + + # Ensure that we have .o objects for linkers which dislike .lo + # (e.g. aix) in case we are running --disable-static + for obj in $libobjs; do + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` + if test ! -f $xdir/$oldobj; then + $show "(cd $xdir && ${LN_S} $baseobj $oldobj)" + $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $? + fi + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + eval cmds=\"$export_symbols_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval cmds=\"$archive_expsym_cmds\" + else + save_deplibs="$deplibs" + for conv in $convenience; do + tmp_deplibs= + for test_deplib in $deplibs; do + if test "$test_deplib" != "$conv"; then + tmp_deplibs="$tmp_deplibs $test_deplib" + fi + done + deplibs="$tmp_deplibs" + done + eval cmds=\"$archive_cmds\" + deplibs="$save_deplibs" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + exit 0 + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit 1 + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${obj}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + eval cmds=\"$reload_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + $show "echo timestamp > $libobj" + $run eval "echo timestamp > $libobj" || exit $? + exit 0 + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + eval cmds=\"$reload_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + else + # Just create a symlink. + $show $rm $libobj + $run $rm $libobj + xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$libobj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` + oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` + $show "(cd $xdir && $LN_S $oldobj $baseobj)" + $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $? + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + ;; + + prog) + case $host in + *cygwin*) output=`echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + ;; + esac + ;; + esac + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ + /* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ + /* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + + #ifdef __cplusplus + extern \"C\" { + #endif + + /* Prevent the only kind of declaration conflicts we can make. */ + #define lt_preloaded_symbols some_other_symbol + + /* External symbol declarations for the compiler. */\ + " + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$output.exp" + $run $rm $export_symbols + $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + else + $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' + $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`echo "$arg" | ${SED} -e 's%^.*/%%'` + $run eval 'echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + + #undef lt_preloaded_symbols + + #if defined (__STDC__) && __STDC__ + # define lt_ptr void * + #else + # define lt_ptr char * + # define const + #endif + + /* The mapping between symbol names and symbols. */ + const struct { + const char *name; + lt_ptr address; + } + lt_preloaded_symbols[] = + {\ + " + + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr) 0} + }; + + /* This works around a problem in FreeBSD linker */ + #ifdef FREEBSD_WORKAROUND + static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; + } + #endif + + #ifdef __cplusplus + } + #endif\ + " + fi + + pic_flag_for_symtable= + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DPIC";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit 1 + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit 0 + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $0 --fallback-echo"; then + case $0 in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; + *) qecho="$SHELL `pwd`/$0 --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`echo $output|${SED} 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) exeext=.exe ;; + *) exeext= ;; + esac + $rm $output + trap "$rm $output; exit 1" 1 2 15 + + $echo > $output "\ + #! $SHELL + + # $output - temporary wrapper script for $objdir/$outputname + # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP + # + # The $output program cannot be directly executed until all the libtool + # libraries that it depends on are installed. + # + # This wrapper script should never be moved out of the build directory. + # If it is, it will not operate correctly. + + # Sed substitution that helps us do robust quoting. It backslashifies + # metacharacters that are still active within double-quoted strings. + Xsed="${SED}"' -e 1s/^X//' + sed_quote_subst='$sed_quote_subst' + + # The HP-UX ksh and POSIX shell print the target directory to stdout + # if CDPATH is set. + if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi + + relink_command=\"$relink_command\" + + # This environment variable determines our operation mode. + if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + notinst_deplibs='$notinst_deplibs' + else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ + " + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" + " + + if test "$fast_install" = yes; then + echo >> $output "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $echo \"\$relink_command_output\" >&2 + $rm \"\$progdir/\$file\" + exit 1 + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + echo >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" + " + fi + + echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 ${SED} + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var + " + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH + " + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + " + case $host in + # win32 systems need to use the prog path for dll + # lookup to work + *-*-cygwin* | *-*-pw32*) + $echo >> $output "\ + exec \$progdir/\$program \${1+\"\$@\"} + " + ;; + + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \$progdir\\\\\$program \${1+\"\$@\"} + " + ;; + + *) + $echo >> $output "\ + # Export the path to the program. + PATH=\"\$progdir:\$PATH\" + export PATH + + exec \$program \${1+\"\$@\"} + " + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit 1 + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi + fi\ + " + chmod +x $output + fi + exit 0 + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$objs$old_deplibs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + # Add in members from convenience archives. + for xlib in $addlibs; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` + done + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + eval cmds=\"$old_archive_from_new_cmds\" + else + # Ensure that we have .o objects in place in case we decided + # not to build a shared library, and have fallen back to building + # static libs even though --disable-static was passed! + for oldobj in $oldobjs; do + if test ! -f $oldobj; then + xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$oldobj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'` + obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` + $show "(cd $xdir && ${LN_S} $obj $baseobj)" + $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $? + fi + done + + eval cmds=\"$old_archive_cmds\" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + # We do not want portage's install root ($D) present. Check only for + # this if the .la is being installed. + if test "$installed" = yes && test "$D"; then + eval mynewdependency_lib="`echo "$libdir/$name" |sed -e "s:$D::g" -e 's://:/:g'`" + else + mynewdependency_lib="$libdir/$name" + fi + # Do not add duplicates + if test "$mynewdependency_lib"; then + if test -z "`echo $newdependency_libs |grep -e "$mynewdependency_lib"`"; then + newdependency_libs="$newdependency_libs $mynewdependency_lib" + fi + fi + ;; + *) + if test "$installed" = yes; then + # Rather use S=WORKDIR if our version of portage supports it. + # This is because some ebuild (gcc) do not use $S as buildroot. + if test "$PWORKDIR"; then + S="$PWORKDIR" + fi + # We do not want portage's build root ($S) present. + if test -n "`echo $deplib |grep -e "$S"`" && test "$S"; then + mynewdependency_lib="" + # We do not want portage's install root ($D) present. + elif test -n "`echo $deplib |grep -e "$D"`" && test "$D"; then + eval mynewdependency_lib="`echo "$deplib" |sed -e "s:$D::g" -e 's://:/:g'`" + else + mynewdependency_lib="$deplib" + fi + else + mynewdependency_lib="$deplib" + fi + # Do not add duplicates + if test "$mynewdependency_lib"; then + if test -z "`echo $newdependency_libs |grep -e "$mynewdependency_lib"`"; then + newdependency_libs="$newdependency_libs $mynewdependency_lib" + fi + fi + ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + # Do not add duplicates + if test "$installed" = yes && test "$D"; then + install_libdir="`echo "$install_libdir" |sed -e "s:$D::g" -e 's://:/:g'`" + fi + $echo > $output "\ + # $outputname - a libtool library file + # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP + # + # Please DO NOT delete this file! + # It is necessary for linking the library. + + # The name that we can dlopen(3). + dlname='$tdlname' + + # Names of this library. + library_names='$library_names' + + # The name of the static archive. + old_library='$old_library' + + # Libraries that this one depends upon. + dependency_libs='$dependency_libs' + + # Version information for $libname. + current=$current + age=$age + revision=$revision + + # Is this an already installed library? + installed=$installed + + # Files to dlopen/dlpreopen + dlopen='$dlfiles' + dlpreopen='$dlprefiles' + + # Directory that this library needs to be installed in: + libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $echo >> $output "\ + relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit 0 + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg="$nonopt" + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest="$arg" + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) prev="-f" ;; + -g) prev="-g" ;; + -m) prev="-m" ;; + -o) prev="-o" ;; + -s) + stripme=" -s" + continue + ;; + -*) ;; + + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest="$arg" + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit 1 + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test $# -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$echo "$destdir" | sed "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + if test "$inst_prefix_dir" = "$destdir"; then + $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 + exit 1 + fi + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$echo "$relink_command" | sed "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$echo "$relink_command" | sed "s%@inst_prefix_dir@%%"` + fi + + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + exit 1 + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test $# -gt 0; then + # Delete the old symlinks, and create new ones. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + eval cmds=\"$postinstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit 0 + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin*|*mingw*) + wrapper=`echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | egrep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $wrapper ;; + *) . ./$wrapper ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 + exit 1 + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $wrapper ;; + *) . ./$wrapper ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir="/tmp" + test -n "$TMPDIR" && tmpdir="$TMPDIR" + tmpdir=`mktemp -d $tmpdir/libtool-XXXXXX 2> /dev/null` + if test $? = 0 ; then : + else + tmpdir="$tmpdir/libtool-$$" + fi + if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : + else + $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 + continue + fi + file=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyways + case $install_prog,$host in + /usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + eval cmds=\"$old_postinstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $0 --finish$current_libdirs' + else + exit 0 + fi + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + eval cmds=\"$finish_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = ":" && exit 0 + + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + echo " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + echo "See any operating system documentation about shared libraries for" + echo "more information, such as the ld(1) and ld.so(8) manual pages." + echo "----------------------------------------------------------------------" + exit 0 + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit 1 + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit 1 + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (${SED} -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved enviroment variables + if test "${save_LC_ALL+set}" = set; then + LC_ALL="$save_LC_ALL"; export LC_ALL + fi + if test "${save_LANG+set}" = set; then + LANG="$save_LANG"; export LANG + fi + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit 0 + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + rmdirs= + + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$objdir" + else + objdir="$dir/$objdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + + if test "$mode" = uninstall; then + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + eval cmds=\"$postuninstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test $? != 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + eval cmds=\"$old_postuninstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test $? != 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + fi + fi + ;; + + *.lo) + if test "$build_old_libs" = yes; then + oldobj=`$echo "X$name" | $Xsed -e "$lo2o"` + rmfiles="$rmfiles $dir/$oldobj" + fi + ;; + + *) + # Do a test to see if this is a libtool program. + if test "$mode" = clean && + (${SED} -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$file + + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + fi + fi # test -z "$show_help" + + if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit 1 + fi + + # We need to display help for each of the modes. + case $mode in + "") $echo \ + "Usage: $modename [OPTION]... [MODE-ARG]... + + Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --version print version information + + MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + + MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for + a more detailed description of MODE." + exit 0 + ;; + + clean) + $echo \ + "Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + + Remove files from the build directory. + + RM is the name of the program to use to delete files associated with each FILE + (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed + to RM. + + If FILE is a libtool library, object or program, all the files associated + with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $echo \ + "Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + + Compile a source file into a libtool library object. + + This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + + COMPILE-COMMAND is a command to be used in creating a \`standard' object file + from the given SOURCEFILE. + + The output file name is determined by removing the directory component from + SOURCEFILE, then substituting the C source code suffix \`.c' with the + library object suffix, \`.lo'." + ;; + + execute) + $echo \ + "Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + + Automatically set library path, then run a program. + + This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + + This mode sets the library path environment variable according to \`-dlopen' + flags. + + If any of the ARGS are libtool executable wrappers, then they are translated + into their corresponding uninstalled binary, and any of their required library + directories are added to the library path. + + Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $echo \ + "Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + + Complete the installation of libtool libraries. + + Each LIBDIR is a directory that contains libtool libraries. + + The commands that this mode executes may require superuser privileges. Use + the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $echo \ + "Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + + Install executables or libraries. + + INSTALL-COMMAND is the installation command. The first component should be + either the \`install' or \`cp' program. + + The rest of the components are interpreted as arguments to that command (only + BSD-compatible install options are recognized)." + ;; + + link) + $echo \ + "Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + + Link object files or libraries together to form another library, or to + create an executable program. + + LINK-COMMAND is a command using the C compiler that you would use to create + a program from several object files. + + The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + + All other options (arguments beginning with \`-') are ignored. + + Every other argument is treated as a filename. Files ending in \`.la' are + treated as uninstalled libtool libraries, other files are standard or library + object files. + + If the OUTPUT-FILE ends in \`.la', then a libtool library is created, + only library objects (\`.lo' files) may be specified, and \`-rpath' is + required, except when creating a convenience library. + + If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created + using \`ar' and \`ranlib', or on Windows using \`lib'. + + If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file + is created, otherwise an executable program is created." + ;; + + uninstall) + $echo \ + "Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + + Remove libraries from an installation directory. + + RM is the name of the program to use to delete files associated with each FILE + (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed + to RM. + + If FILE is a libtool library, all the files associated with it are deleted. + Otherwise, only FILE itself is deleted using RM." + ;; + + *) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + echo + $echo "Try \`$modename --help' for more information about other modes." + + exit 0 + + # Local Variables: + # mode:shell-script + # sh-indentation:2 + # End: Index: llvm-java/autoconf/mkinstalldirs diff -c /dev/null llvm-java/autoconf/mkinstalldirs:1.1 *** /dev/null Thu Apr 15 16:01:00 2004 --- llvm-java/autoconf/mkinstalldirs Thu Apr 15 16:00:49 2004 *************** *** 0 **** --- 1,101 ---- + #! /bin/sh + # mkinstalldirs --- make directory hierarchy + # Author: Noah Friedman + # Created: 1993-05-16 + # Public domain + + # $Id: mkinstalldirs,v 1.1 2004/04/15 21:00:49 alkis Exp $ + + errstatus=0 + dirmode="" + + usage="\ + Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + + # process command line arguments + while test $# -gt 0 ; do + case "${1}" in + -h | --help | --h* ) # -h for help + echo "${usage}" 1>&2; exit 0 ;; + -m ) # -m PERM arg + shift + test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; } + dirmode="${1}" + shift ;; + -- ) shift; break ;; # stop option processing + -* ) echo "${usage}" 1>&2; exit 1 ;; # unknown option + * ) break ;; # first non-opt arg + esac + done + + for file + do + if test -d "$file"; then + shift + else + break + fi + done + + case $# in + 0) exit 0 ;; + esac + + case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi ;; + esac + + for file + do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done + done + + exit $errstatus + + # Local Variables: + # mode: shell-script + # sh-indentation: 3 + # End: + # mkinstalldirs ends here From alkis at cs.uiuc.edu Thu Apr 15 16:01:57 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 16:01:57 2004 Subject: [llvm-commits] CVS: llvm-java/lib/Makefile Message-ID: <200404152101.QAA10563@zion.cs.uiuc.edu> Changes in directory llvm-java/lib: Makefile added (r1.1) --- Log message: Initial checking of the llvm java-frontend. This contains a skeleton and a preliminary ClassFile parsing library --- Diffs of the changes: (+13 -0) Index: llvm-java/lib/Makefile diff -c /dev/null llvm-java/lib/Makefile:1.1 *** /dev/null Thu Apr 15 16:01:00 2004 --- llvm-java/lib/Makefile Thu Apr 15 16:00:50 2004 *************** *** 0 **** --- 1,13 ---- + ##===- lib/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 = .. + + PARALLEL_DIRS = ClassFile + + include $(LEVEL)/Makefile.common From alkis at cs.uiuc.edu Thu Apr 15 16:02:07 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 16:02:07 2004 Subject: [llvm-commits] CVS: llvm-java/tools/classdump/Makefile classdump.cpp Message-ID: <200404152101.QAA10590@zion.cs.uiuc.edu> Changes in directory llvm-java/tools/classdump: Makefile added (r1.1) classdump.cpp added (r1.1) --- Log message: Initial checking of the llvm java-frontend. This contains a skeleton and a preliminary ClassFile parsing library --- Diffs of the changes: (+47 -0) Index: llvm-java/tools/classdump/Makefile diff -c /dev/null llvm-java/tools/classdump/Makefile:1.1 *** /dev/null Thu Apr 15 16:01:00 2004 --- llvm-java/tools/classdump/Makefile Thu Apr 15 16:00:50 2004 *************** *** 0 **** --- 1,13 ---- + #===- tools/llc/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 = ../.. + TOOLNAME = dumpclass + USEDLIBS = classfile + + include $(LEVEL)/Makefile.common Index: llvm-java/tools/classdump/classdump.cpp diff -c /dev/null llvm-java/tools/classdump/classdump.cpp:1.1 *** /dev/null Thu Apr 15 16:01:00 2004 --- llvm-java/tools/classdump/classdump.cpp Thu Apr 15 16:00:50 2004 *************** *** 0 **** --- 1,34 ---- + //===-- ClassFile.h - ClassFile support library -----------------*- 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 file a sample class reader driver. It is used to drive class + // reader tests. + // + //===----------------------------------------------------------------------===// + + #include + + #include + #include + + using namespace llvm; + + int main(int argc, char* argv[]) + { + try { + Java::ClassFile* cf = Java::ClassFile::readClassFile(std::cin); + cf->dump(std::cout); + } + catch (std::exception& e) { + std::cerr << e.what() << '\n'; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; + } From brukman at cs.uiuc.edu Thu Apr 15 16:03:05 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Thu Apr 15 16:03:05 2004 Subject: [llvm-commits] CVS: llvm/docs/HowToSubmitABug.html Message-ID: <200404152101.QAA14726@zion.cs.uiuc.edu> Changes in directory llvm/docs: HowToSubmitABug.html updated: 1.14 -> 1.15 --- Log message: Add note about easier way to debug tests in the llvm tree. --- Diffs of the changes: (+11 -1) Index: llvm/docs/HowToSubmitABug.html diff -u llvm/docs/HowToSubmitABug.html:1.14 llvm/docs/HowToSubmitABug.html:1.15 --- llvm/docs/HowToSubmitABug.html:1.14 Thu Apr 15 15:49:32 2004 +++ llvm/docs/HowToSubmitABug.html Thu Apr 15 16:01:21 2004 @@ -274,6 +274,16 @@ --args -- [program arguments]

    +

    Special note: if you are debugging MultiSource or SPEC tests that +already exist in the llvm/test hierarchy, there is an easier way to +debug the JIT, LLC, and CBE, using the pre-written Makefile targets, which +will pass the program options specified in the Makefiles:

    + +
    +

    cd llvm/test/../../program
    + make bugpoint-jit

    +
    +

    At the end of a successful bugpoint run, you will be presented with two bytecode files: a safe file which can be compiled with the C backend and the test file which either LLC or the JIT @@ -322,7 +332,7 @@ Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/04/15 20:49:32 $ + Last modified: $Date: 2004/04/15 21:01:21 $ From alkis at cs.uiuc.edu Thu Apr 15 23:04:01 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 23:04:01 2004 Subject: [llvm-commits] CVS: llvm-java/Makefile Message-ID: <200404160403.XAA04917@zion.cs.uiuc.edu> Changes in directory llvm-java: Makefile updated: 1.1 -> 1.2 --- Log message: Update file descriptions and clean up Makefiles --- Diffs of the changes: (+2 -2) Index: llvm-java/Makefile diff -u llvm-java/Makefile:1.1 llvm-java/Makefile:1.2 --- llvm-java/Makefile:1.1 Thu Apr 15 16:00:49 2004 +++ llvm-java/Makefile Thu Apr 15 23:03:45 2004 @@ -6,8 +6,8 @@ # the University of Illinois Open Source License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## -LEVEL = . +LEVEL := . -DIRS = lib tools +DIRS := lib tools include $(LEVEL)/Makefile.common From alkis at cs.uiuc.edu Thu Apr 15 23:04:11 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 23:04:11 2004 Subject: [llvm-commits] CVS: llvm-java/include/llvm/Java/ClassFile.h Message-ID: <200404160403.XAA04924@zion.cs.uiuc.edu> Changes in directory llvm-java/include/llvm/Java: ClassFile.h updated: 1.1 -> 1.2 --- Log message: Update file descriptions and clean up Makefiles --- Diffs of the changes: (+2 -3) Index: llvm-java/include/llvm/Java/ClassFile.h diff -u llvm-java/include/llvm/Java/ClassFile.h:1.1 llvm-java/include/llvm/Java/ClassFile.h:1.2 --- llvm-java/include/llvm/Java/ClassFile.h:1.1 Thu Apr 15 16:00:50 2004 +++ llvm-java/include/llvm/Java/ClassFile.h Thu Apr 15 23:03:45 2004 @@ -7,9 +7,8 @@ // //===----------------------------------------------------------------------===// // -// This file contains the declaration of the ClassFileReader class, -// which implements a ClassFile reader parser for use with the Java -// frontend. +// This file contains the declaration of the ClassFile and subordinate +// classes, which represent a parsed class file. // //===----------------------------------------------------------------------===// From alkis at cs.uiuc.edu Thu Apr 15 23:04:20 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 23:04:20 2004 Subject: [llvm-commits] CVS: llvm-java/lib/ClassFile/Makefile Message-ID: <200404160403.XAA04938@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/ClassFile: Makefile updated: 1.1 -> 1.2 --- Log message: Update file descriptions and clean up Makefiles --- Diffs of the changes: (+5 -4) Index: llvm-java/lib/ClassFile/Makefile diff -u llvm-java/lib/ClassFile/Makefile:1.1 llvm-java/lib/ClassFile/Makefile:1.2 --- llvm-java/lib/ClassFile/Makefile:1.1 Thu Apr 15 16:00:50 2004 +++ llvm-java/lib/ClassFile/Makefile Thu Apr 15 23:03:45 2004 @@ -1,4 +1,4 @@ -##===- lib/Analysis/Makefile -------------------------------*- Makefile -*-===## +##===- lib/ClassFile/Makefile ------------------------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # @@ -6,9 +6,10 @@ # the University of Illinois Open Source License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## +LEVEL := ../.. -LEVEL = ../.. -LIBRARYNAME = classfile -#BUILD_ARCHIVE = 1 +LIBRARYNAME := classfile + +BUILD_ARCHIVE = 1 include $(LEVEL)/Makefile.common From alkis at cs.uiuc.edu Thu Apr 15 23:04:29 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 23:04:29 2004 Subject: [llvm-commits] CVS: llvm-java/lib/Makefile Message-ID: <200404160403.XAA04931@zion.cs.uiuc.edu> Changes in directory llvm-java/lib: Makefile updated: 1.1 -> 1.2 --- Log message: Update file descriptions and clean up Makefiles --- Diffs of the changes: (+2 -2) Index: llvm-java/lib/Makefile diff -u llvm-java/lib/Makefile:1.1 llvm-java/lib/Makefile:1.2 --- llvm-java/lib/Makefile:1.1 Thu Apr 15 16:00:50 2004 +++ llvm-java/lib/Makefile Thu Apr 15 23:03:45 2004 @@ -6,8 +6,8 @@ # the University of Illinois Open Source License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## -LEVEL = .. +LEVEL := .. -PARALLEL_DIRS = ClassFile +PARALLEL_DIRS := ClassFile include $(LEVEL)/Makefile.common From alkis at cs.uiuc.edu Thu Apr 15 23:04:38 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 23:04:38 2004 Subject: [llvm-commits] CVS: llvm-java/tools/Makefile Message-ID: <200404160403.XAA04945@zion.cs.uiuc.edu> Changes in directory llvm-java/tools: Makefile updated: 1.1 -> 1.2 --- Log message: Update file descriptions and clean up Makefiles --- Diffs of the changes: (+1 -1) Index: llvm-java/tools/Makefile diff -u llvm-java/tools/Makefile:1.1 llvm-java/tools/Makefile:1.2 --- llvm-java/tools/Makefile:1.1 Thu Apr 15 16:00:50 2004 +++ llvm-java/tools/Makefile Thu Apr 15 23:03:45 2004 @@ -6,8 +6,8 @@ # the University of Illinois Open Source License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## - LEVEL := .. + PARALLEL_DIRS := classdump include $(LEVEL)/Makefile.common From alkis at cs.uiuc.edu Thu Apr 15 23:04:47 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 23:04:47 2004 Subject: [llvm-commits] CVS: llvm-java/tools/classdump/Makefile classdump.cpp Message-ID: <200404160403.XAA04954@zion.cs.uiuc.edu> Changes in directory llvm-java/tools/classdump: Makefile updated: 1.1 -> 1.2 classdump.cpp updated: 1.1 -> 1.2 --- Log message: Update file descriptions and clean up Makefiles --- Diffs of the changes: (+7 -5) Index: llvm-java/tools/classdump/Makefile diff -u llvm-java/tools/classdump/Makefile:1.1 llvm-java/tools/classdump/Makefile:1.2 --- llvm-java/tools/classdump/Makefile:1.1 Thu Apr 15 16:00:50 2004 +++ llvm-java/tools/classdump/Makefile Thu Apr 15 23:03:45 2004 @@ -1,4 +1,4 @@ -#===- tools/llc/Makefile ------------------------------*- Makefile -*-===## +#===- tools/classdump/Makefile -----------------------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # @@ -6,8 +6,10 @@ # the University of Illinois Open Source License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## -LEVEL = ../.. -TOOLNAME = dumpclass -USEDLIBS = classfile +LEVEL := ../.. + +TOOLNAME := classdump + +USEDLIBS := classfile include $(LEVEL)/Makefile.common Index: llvm-java/tools/classdump/classdump.cpp diff -u llvm-java/tools/classdump/classdump.cpp:1.1 llvm-java/tools/classdump/classdump.cpp:1.2 --- llvm-java/tools/classdump/classdump.cpp:1.1 Thu Apr 15 16:00:50 2004 +++ llvm-java/tools/classdump/classdump.cpp Thu Apr 15 23:03:45 2004 @@ -1,4 +1,4 @@ -//===-- ClassFile.h - ClassFile support library -----------------*- C++ -*-===// +//===-- classdump.cpp - classdump utility -----------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // From alkis at cs.uiuc.edu Thu Apr 15 23:08:01 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 23:08:01 2004 Subject: [llvm-commits] CVS: llvm-java/autoconf/configure.ac Message-ID: <200404160407.XAA05901@zion.cs.uiuc.edu> Changes in directory llvm-java/autoconf: configure.ac updated: 1.1 -> 1.2 --- Log message: More textual fixes --- Diffs of the changes: (+1 -1) Index: llvm-java/autoconf/configure.ac diff -u llvm-java/autoconf/configure.ac:1.1 llvm-java/autoconf/configure.ac:1.2 --- llvm-java/autoconf/configure.ac:1.1 Thu Apr 15 16:00:49 2004 +++ llvm-java/autoconf/configure.ac Thu Apr 15 23:07:41 2004 @@ -1,7 +1,7 @@ dnl ************************************************************************** dnl * Initialize dnl ************************************************************************** -AC_INIT([[[ModuleMaker]]],[[[x.xx]]],[bugs at yourdomain]) +AC_INIT([Java],[0.0],[llvmbugs at cs.uiuc.edu]) dnl Place all of the extra autoconf files into the config subdirectory AC_CONFIG_AUX_DIR([autoconf]) From alkis at cs.uiuc.edu Thu Apr 15 23:08:10 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 23:08:10 2004 Subject: [llvm-commits] CVS: llvm-java/configure Message-ID: <200404160407.XAA05899@zion.cs.uiuc.edu> Changes in directory llvm-java: configure updated: 1.1 -> 1.2 --- Log message: More textual fixes --- Diffs of the changes: (+14 -14) Index: llvm-java/configure diff -u llvm-java/configure:1.1 llvm-java/configure:1.2 --- llvm-java/configure:1.1 Thu Apr 15 16:00:49 2004 +++ llvm-java/configure Thu Apr 15 23:07:41 2004 @@ -1,8 +1,8 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.58 for [ModuleMaker] [x.xx]. +# Generated by GNU Autoconf 2.58 for Java 0.0. # -# Report bugs to . +# Report bugs to . # # Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation @@ -267,11 +267,11 @@ : ${ac_max_here_lines=38} # Identity of this package. -PACKAGE_NAME='[ModuleMaker]' -PACKAGE_TARNAME='--modulemaker--' -PACKAGE_VERSION='[x.xx]' -PACKAGE_STRING='[ModuleMaker] [x.xx]' -PACKAGE_BUGREPORT='bugs at yourdomain' +PACKAGE_NAME='Java' +PACKAGE_TARNAME='java' +PACKAGE_VERSION='0.0' +PACKAGE_STRING='Java 0.0' +PACKAGE_BUGREPORT='llvmbugs at cs.uiuc.edu' ac_unique_file=""Makefile.common.in"" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS LLVM_SRC LLVM_OBJ LIBOBJS LTLIBOBJS' @@ -723,7 +723,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures [ModuleMaker] [x.xx] to adapt to many kinds of systems. +\`configure' configures Java 0.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -780,7 +780,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of [ModuleMaker] [x.xx]:";; + short | recursive ) echo "Configuration of Java 0.0:";; esac cat <<\_ACEOF @@ -790,7 +790,7 @@ --with-llvmsrc Location of LLVM Source Code --with-llvmobj Location of LLVM Object Code -Report bugs to . +Report bugs to . _ACEOF fi @@ -883,7 +883,7 @@ test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -[ModuleMaker] configure [x.xx] +Java configure 0.0 generated by GNU Autoconf 2.58 Copyright (C) 2003 Free Software Foundation, Inc. @@ -897,7 +897,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by [ModuleMaker] $as_me [x.xx], which was +It was created by Java $as_me 0.0, which was generated by GNU Autoconf 2.58. Invocation command line was $ $0 $@ @@ -1704,7 +1704,7 @@ } >&5 cat >&5 <<_CSEOF -This file was extended by [ModuleMaker] $as_me [x.xx], which was +This file was extended by Java $as_me 0.0, which was generated by GNU Autoconf 2.58. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -1762,7 +1762,7 @@ cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -[ModuleMaker] config.status [x.xx] +Java config.status 0.0 configured by $0, generated by GNU Autoconf 2.58, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" From alkis at cs.uiuc.edu Thu Apr 15 23:21:01 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 23:21:01 2004 Subject: [llvm-commits] CVS: llvm-java/autoconf/configure.ac Message-ID: <200404160420.XAA06265@zion.cs.uiuc.edu> Changes in directory llvm-java/autoconf: configure.ac updated: 1.2 -> 1.3 --- Log message: Add check for the jikes compiler --- Diffs of the changes: (+10 -9) Index: llvm-java/autoconf/configure.ac diff -u llvm-java/autoconf/configure.ac:1.2 llvm-java/autoconf/configure.ac:1.3 --- llvm-java/autoconf/configure.ac:1.2 Thu Apr 15 23:07:41 2004 +++ llvm-java/autoconf/configure.ac Thu Apr 15 23:20:01 2004 @@ -1,10 +1,10 @@ dnl ************************************************************************** dnl * Initialize dnl ************************************************************************** -AC_INIT([Java],[0.0],[llvmbugs at cs.uiuc.edu]) +AC_INIT(Java, 0.0, llvmbugs at cs.uiuc.edu) dnl Place all of the extra autoconf files into the config subdirectory -AC_CONFIG_AUX_DIR([autoconf]) +AC_CONFIG_AUX_DIR(autoconf) dnl Configure a header file @@ -24,9 +24,10 @@ dnl ************************************************************************** dnl * Check for programs. dnl ************************************************************************** +AC_CHECK_PROG(JIKES, jikes) dnl Verify that the source directory is valid -AC_CONFIG_SRCDIR(["Makefile.common.in"]) +AC_CONFIG_SRCDIR(Makefile.common.in) dnl ************************************************************************** dnl * Check for libraries. @@ -54,15 +55,15 @@ dnl Location of LLVM source code AC_ARG_WITH(llvmsrc, - AC_HELP_STRING([--with-llvmsrc],[Location of LLVM Source Code]), - AC_SUBST(LLVM_SRC,[$withval]), - AC_SUBST(LLVM_SRC,[`cd ${srcdir}/../..; pwd`])) + AC_HELP_STRING(--with-llvmsrc,Location of LLVM Source Code), + AC_SUBST(LLVM_SRC,$withval), + AC_SUBST(LLVM_SRC,`cd ${srcdir}/../..; pwd`)) dnl Location of LLVM object code AC_ARG_WITH(llvmobj, - AC_HELP_STRING([--with-llvmobj],[Location of LLVM Object Code]), - AC_SUBST(LLVM_OBJ,[$withval]), - AC_SUBST(LLVM_OBJ,[`cd ../..; pwd`])) + AC_HELP_STRING(--with-llvmobj,Location of LLVM Object Code), + AC_SUBST(LLVM_OBJ,$withval), + AC_SUBST(LLVM_OBJ,`cd ../..; pwd`)) dnl ************************************************************************** dnl * Create the output files From alkis at cs.uiuc.edu Thu Apr 15 23:21:11 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 23:21:11 2004 Subject: [llvm-commits] CVS: llvm-java/configure Message-ID: <200404160420.XAA06266@zion.cs.uiuc.edu> Changes in directory llvm-java: configure updated: 1.2 -> 1.3 --- Log message: Add check for the jikes compiler --- Diffs of the changes: (+38 -2) Index: llvm-java/configure diff -u llvm-java/configure:1.2 llvm-java/configure:1.3 --- llvm-java/configure:1.2 Thu Apr 15 23:07:41 2004 +++ llvm-java/configure Thu Apr 15 23:19:31 2004 @@ -273,8 +273,8 @@ PACKAGE_STRING='Java 0.0' PACKAGE_BUGREPORT='llvmbugs at cs.uiuc.edu' -ac_unique_file=""Makefile.common.in"" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS LLVM_SRC LLVM_OBJ LIBOBJS LTLIBOBJS' +ac_unique_file="Makefile.common.in" +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS JIKES LLVM_SRC LLVM_OBJ LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -1279,6 +1279,41 @@ +# Extract the first word of "jikes", so it can be a program name with args. +set dummy jikes; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_JIKES+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$JIKES"; then + ac_cv_prog_JIKES="$JIKES" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_JIKES="" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +JIKES=$ac_cv_prog_JIKES +if test -n "$JIKES"; then + echo "$as_me:$LINENO: result: $JIKES" >&5 +echo "${ECHO_T}$JIKES" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + @@ -1965,6 +2000,7 @@ s, at ECHO_N@,$ECHO_N,;t t s, at ECHO_T@,$ECHO_T,;t t s, at LIBS@,$LIBS,;t t +s, at JIKES@,$JIKES,;t t s, at LLVM_SRC@,$LLVM_SRC,;t t s, at LLVM_OBJ@,$LLVM_OBJ,;t t s, at LIBOBJS@,$LIBOBJS,;t t From alkis at cs.uiuc.edu Thu Apr 15 23:38:01 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 23:38:01 2004 Subject: [llvm-commits] CVS: llvm-java/autoconf/configure.ac Message-ID: <200404160438.XAA07530@zion.cs.uiuc.edu> Changes in directory llvm-java/autoconf: configure.ac updated: 1.3 -> 1.4 --- Log message: Fix jikes detection --- Diffs of the changes: (+1 -1) Index: llvm-java/autoconf/configure.ac diff -u llvm-java/autoconf/configure.ac:1.3 llvm-java/autoconf/configure.ac:1.4 --- llvm-java/autoconf/configure.ac:1.3 Thu Apr 15 23:20:01 2004 +++ llvm-java/autoconf/configure.ac Thu Apr 15 23:37:54 2004 @@ -24,7 +24,7 @@ dnl ************************************************************************** dnl * Check for programs. dnl ************************************************************************** -AC_CHECK_PROG(JIKES, jikes) +AC_CHECK_PROG(JIKES, jikes, jikes) dnl Verify that the source directory is valid AC_CONFIG_SRCDIR(Makefile.common.in) From alkis at cs.uiuc.edu Thu Apr 15 23:38:11 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 23:38:11 2004 Subject: [llvm-commits] CVS: llvm-java/configure Message-ID: <200404160438.XAA07525@zion.cs.uiuc.edu> Changes in directory llvm-java: configure updated: 1.3 -> 1.4 --- Log message: Fix jikes detection --- Diffs of the changes: (+1 -1) Index: llvm-java/configure diff -u llvm-java/configure:1.3 llvm-java/configure:1.4 --- llvm-java/configure:1.3 Thu Apr 15 23:19:31 2004 +++ llvm-java/configure Thu Apr 15 23:37:54 2004 @@ -1296,7 +1296,7 @@ test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_JIKES="" + ac_cv_prog_JIKES="jikes" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi From alkis at cs.uiuc.edu Thu Apr 15 23:41:02 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Thu Apr 15 23:41:02 2004 Subject: [llvm-commits] CVS: llvm-java/test/ Message-ID: <200404160441.XAA07707@zion.cs.uiuc.edu> Changes in directory llvm-java/test: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm-java/test added to the repository --- Diffs of the changes: (+0 -0) From lattner at cs.uiuc.edu Fri Apr 16 00:18:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Apr 16 00:18:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/InlineFunction.cpp Message-ID: <200404160518.AAA12380@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: InlineFunction.cpp updated: 1.24 -> 1.25 --- Log message: Fix Inline/2004-04-15-InlineDeletesCall.ll Basically we were using SimplifyCFG as a huge sledgehammer for a simple optimization. Because simplifycfg does so many things, we can't use it for this purpose. --- Diffs of the changes: (+20 -12) Index: llvm/lib/Transforms/Utils/InlineFunction.cpp diff -u llvm/lib/Transforms/Utils/InlineFunction.cpp:1.24 llvm/lib/Transforms/Utils/InlineFunction.cpp:1.25 --- llvm/lib/Transforms/Utils/InlineFunction.cpp:1.24 Fri Feb 13 10:47:35 2004 +++ llvm/lib/Transforms/Utils/InlineFunction.cpp Fri Apr 16 00:17:59 2004 @@ -22,7 +22,6 @@ #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" #include "llvm/Support/CallSite.h" -#include "llvm/Transforms/Utils/Local.h" using namespace llvm; bool llvm::InlineFunction(CallInst *CI) { return InlineFunction(CallSite(CI)); } @@ -302,11 +301,17 @@ if (!TheCall->use_empty()) TheCall->replaceAllUsesWith(Returns[0]->getReturnValue()); - // Add a branch to the merge point where the PHI node lives if it exists. - new BranchInst(AfterCallBB, Returns[0]); + // Splice the code from the return block into the block that it will return + // to, which contains the code that was after the call. + BasicBlock *ReturnBB = Returns[0]->getParent(); + ReturnBB->getInstList().splice(Returns[0], AfterCallBB->getInstList()); + + // Update PHI nodes that use the AfterCallBB to use the ReturnBB. + AfterCallBB->replaceAllUsesWith(ReturnBB); - // Delete the return instruction now + // Delete the return instruction now and empty AfterCallBB now. Returns[0]->getParent()->getInstList().erase(Returns[0]); + Caller->getBasicBlockList().erase(AfterCallBB); } // Since we are now done with the Call/Invoke, we can delete it. @@ -314,15 +319,18 @@ // We should always be able to fold the entry block of the function into the // single predecessor of the block... - assert(cast(Br)->isUnconditional() &&"splitBasicBlock broken!"); + assert(cast(Br)->isUnconditional() && "splitBasicBlock broken!"); BasicBlock *CalleeEntry = cast(Br)->getSuccessor(0); - SimplifyCFG(CalleeEntry); - - // Okay, continue the CFG cleanup. It's often the case that there is only a - // single return instruction in the callee function. If this is the case, - // then we have an unconditional branch from the return block to the - // 'AfterCallBB'. Check for this case, and eliminate the branch is possible. - SimplifyCFG(AfterCallBB); + // Splice the code entry block into calling block, right before the + // unconditional branch. + OrigBB->getInstList().splice(Br, CalleeEntry->getInstList()); + CalleeEntry->replaceAllUsesWith(OrigBB); // Update PHI nodes + + // Remove the unconditional branch. + OrigBB->getInstList().erase(Br); + + // Now we can remove the CalleeEntry block, which is now empty. + Caller->getBasicBlockList().erase(CalleeEntry); return true; } From lattner at cs.uiuc.edu Fri Apr 16 00:36:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Apr 16 00:36:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Support/SystemUtils.cpp Message-ID: <200404160536.AAA17333@zion.cs.uiuc.edu> Changes in directory llvm/lib/Support: SystemUtils.cpp updated: 1.23 -> 1.24 --- Log message: Bugpoint was not correctly capturing stderr! This caused it to "find" bugs that didn't exist, missing the ones that do :( --- Diffs of the changes: (+4 -1) Index: llvm/lib/Support/SystemUtils.cpp diff -u llvm/lib/Support/SystemUtils.cpp:1.23 llvm/lib/Support/SystemUtils.cpp:1.24 --- llvm/lib/Support/SystemUtils.cpp:1.23 Fri Apr 2 15:26:04 2004 +++ llvm/lib/Support/SystemUtils.cpp Fri Apr 16 00:35:58 2004 @@ -142,7 +142,10 @@ case 0: // Child RedirectFD(StdInFile, 0); // Redirect file descriptors... RedirectFD(StdOutFile, 1); - RedirectFD(StdErrFile, 2); + if (StdOutFile != StdErrFile) + RedirectFD(StdErrFile, 2); + else + dup2(1, 2); execv(ProgramPath.c_str(), (char *const *)Args); std::cerr << "Error executing program: '" << ProgramPath; From lattner at cs.uiuc.edu Fri Apr 16 00:52:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Apr 16 00:52:01 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Verifier.cpp Message-ID: <200404160551.AAA19921@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Verifier.cpp updated: 1.95 -> 1.96 --- Log message: Make sure to check for a very bad class of errors: an instruction that does not dominate all of its users, but is in the same basic block as its users. This class of error is what caused the mysterious CBE only failures last night. --- Diffs of the changes: (+6 -0) Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.95 llvm/lib/VMCore/Verifier.cpp:1.96 --- llvm/lib/VMCore/Verifier.cpp:1.95 Wed Apr 14 10:06:48 2004 +++ llvm/lib/VMCore/Verifier.cpp Fri Apr 16 00:51:47 2004 @@ -559,6 +559,12 @@ // exceptional destination. if (InvokeInst *II = dyn_cast(Op)) OpBlock = II->getNormalDest(); + 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), + "Instruction does not dominate all uses!", Op, &I); + } // Definition must dominate use unless use is unreachable! Assert2(DS->dominates(OpBlock, BB) || From lattner at cs.uiuc.edu Fri Apr 16 01:04:00 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Apr 16 01:04:00 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <200404160603.BAA21198@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: IndVarSimplify.cpp updated: 1.55 -> 1.56 --- Log message: Fix some of the strange CBE-only failures that happened last night. --- Diffs of the changes: (+1 -0) Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp diff -u llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.55 llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.56 --- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.55 Thu Apr 15 15:26:22 2004 +++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Fri Apr 16 01:03:17 2004 @@ -386,6 +386,7 @@ // Now that we know the largest of of the induction variables in this loop, // insert a canonical induction variable of the largest size. + LargestType = LargestType->getUnsignedVersion(); Value *IndVar = Rewriter.GetOrInsertCanonicalInductionVariable(L,LargestType); ++NumInserted; Changed = true; From lattner at cs.uiuc.edu Fri Apr 16 09:13:04 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Apr 16 09:13:04 2004 Subject: [llvm-commits] CVS: llvm/runtime/Makefile Message-ID: <200404161412.JAA24560@zion.cs.uiuc.edu> Changes in directory llvm/runtime: Makefile updated: 1.16 -> 1.17 --- Log message: Remove libraries that have no reason to be here, and keep breaking the nightly tester because their makefiles do not have the right dependencies!! --- Diffs of the changes: (+1 -1) Index: llvm/runtime/Makefile diff -u llvm/runtime/Makefile:1.16 llvm/runtime/Makefile:1.17 --- llvm/runtime/Makefile:1.16 Tue Apr 13 11:24:53 2004 +++ llvm/runtime/Makefile Fri Apr 16 09:12:36 2004 @@ -12,7 +12,7 @@ include $(LEVEL)/Makefile.config ifneq ($(wildcard $(LLVMGCCDIR)),) -PARALLEL_DIRS := GCCLibraries libdummy libprofile libtrace libpng zlib +PARALLEL_DIRS := GCCLibraries libdummy libprofile libtrace else PARALLEL_DIRS := install all :: From brukman at cs.uiuc.edu Fri Apr 16 10:47:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Apr 16 10:47:01 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/Instruction.h Message-ID: <200404161546.KAA09971@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: Instruction.h updated: 1.51 -> 1.52 --- Log message: Assert if Instruction is being deleted before being removed from BasicBlock. --- Diffs of the changes: (+4 -0) Index: llvm/include/llvm/Instruction.h diff -u llvm/include/llvm/Instruction.h:1.51 llvm/include/llvm/Instruction.h:1.52 --- llvm/include/llvm/Instruction.h:1.51 Sun Feb 29 12:54:23 2004 +++ llvm/include/llvm/Instruction.h Fri Apr 16 10:46:43 2004 @@ -43,6 +43,10 @@ Instruction *InsertBefore = 0); public: + ~Instruction() { + assert(Parent == 0 && "Instruction still linked in the program!"); + } + // Specialize setName to handle symbol table majik... virtual void setName(const std::string &name, SymbolTable *ST = 0); From brukman at cs.uiuc.edu Fri Apr 16 10:48:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Apr 16 10:48:01 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/BasicBlock.cpp Message-ID: <200404161547.KAA10184@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: BasicBlock.cpp updated: 1.42 -> 1.43 --- Log message: Assert if deleting BasicBlock before removing it from Function. --- Diffs of the changes: (+1 -0) Index: llvm/lib/VMCore/BasicBlock.cpp diff -u llvm/lib/VMCore/BasicBlock.cpp:1.42 llvm/lib/VMCore/BasicBlock.cpp:1.43 --- llvm/lib/VMCore/BasicBlock.cpp:1.42 Tue Feb 10 19:17:33 2004 +++ llvm/lib/VMCore/BasicBlock.cpp Fri Apr 16 10:47:21 2004 @@ -81,6 +81,7 @@ BasicBlock::~BasicBlock() { + assert(Parent == 0 && "BasicBlock still linked into the program!"); dropAllReferences(); InstList.clear(); } From gaeke at cs.uiuc.edu Fri Apr 16 10:57:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Apr 16 10:57:01 2004 Subject: [llvm-commits] CVS: llvm/Makefile Message-ID: <200404161557.KAA14388@zion.cs.uiuc.edu> Changes in directory llvm: Makefile updated: 1.22 -> 1.23 --- Log message: As a part of the bootstrapping process, the top-level tools-only target should not build projects. --- Diffs of the changes: (+1 -1) Index: llvm/Makefile diff -u llvm/Makefile:1.22 llvm/Makefile:1.23 --- llvm/Makefile:1.22 Mon Feb 9 19:10:01 2004 +++ llvm/Makefile Fri Apr 16 10:57:02 2004 @@ -8,10 +8,10 @@ ##===----------------------------------------------------------------------===## LEVEL = . DIRS = lib/Support utils lib tools -OPTIONAL_DIRS = projects ifneq ($(MAKECMDGOALS),tools-only) DIRS += runtime +OPTIONAL_DIRS = projects endif include $(LEVEL)/Makefile.common From gaeke at cs.uiuc.edu Fri Apr 16 10:57:11 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Apr 16 10:57:11 2004 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineInstr.h Message-ID: <200404161557.KAA14429@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineInstr.h updated: 1.145 -> 1.146 --- Log message: Include for compatibility with gcc 3.0.x (the system compiler on Debian.) --- Diffs of the changes: (+1 -0) Index: llvm/include/llvm/CodeGen/MachineInstr.h diff -u llvm/include/llvm/CodeGen/MachineInstr.h:1.145 llvm/include/llvm/CodeGen/MachineInstr.h:1.146 --- llvm/include/llvm/CodeGen/MachineInstr.h:1.145 Thu Mar 4 12:02:07 2004 +++ llvm/include/llvm/CodeGen/MachineInstr.h Fri Apr 16 10:57:14 2004 @@ -17,6 +17,7 @@ #define LLVM_CODEGEN_MACHINEINSTR_H #include "Support/iterator" +#include #include #include From gaeke at cs.uiuc.edu Fri Apr 16 10:58:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Apr 16 10:58:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/Local.cpp Message-ID: <200404161557.KAA14472@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: Local.cpp updated: 1.19 -> 1.20 --- Log message: Include for compatibility with gcc 3.0.x (the system compiler on Debian.) --- Diffs of the changes: (+1 -0) Index: llvm/lib/Transforms/Utils/Local.cpp diff -u llvm/lib/Transforms/Utils/Local.cpp:1.19 llvm/lib/Transforms/Utils/Local.cpp:1.20 --- llvm/lib/Transforms/Utils/Local.cpp:1.19 Tue Apr 13 14:28:52 2004 +++ llvm/lib/Transforms/Utils/Local.cpp Fri Apr 16 10:57:32 2004 @@ -15,6 +15,7 @@ #include "llvm/Transforms/Utils/Local.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" +#include using namespace llvm; //===----------------------------------------------------------------------===// From gaeke at cs.uiuc.edu Fri Apr 16 10:58:11 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Apr 16 10:58:11 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ScalarEvolution.cpp Message-ID: <200404161557.KAA14479@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ScalarEvolution.cpp updated: 1.11 -> 1.12 --- Log message: Include for compatibility with gcc 3.0.x (the system compiler on Debian.) --- Diffs of the changes: (+1 -0) Index: llvm/lib/Analysis/ScalarEvolution.cpp diff -u llvm/lib/Analysis/ScalarEvolution.cpp:1.11 llvm/lib/Analysis/ScalarEvolution.cpp:1.12 --- llvm/lib/Analysis/ScalarEvolution.cpp:1.11 Thu Apr 15 10:07:24 2004 +++ llvm/lib/Analysis/ScalarEvolution.cpp Fri Apr 16 10:57:32 2004 @@ -76,6 +76,7 @@ #include "llvm/Support/ConstantRange.h" #include "llvm/Support/InstIterator.h" #include "Support/Statistic.h" +#include using namespace llvm; namespace { From lattner at cs.uiuc.edu Fri Apr 16 11:03:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Apr 16 11:03:01 2004 Subject: [llvm-commits] CVS: llvm-www/www-index.html Message-ID: <200404161602.LAA15172@zion.cs.uiuc.edu> Changes in directory llvm-www: www-index.html updated: 1.98 -> 1.99 --- Log message: Add a new section. This can probably be improved, but it's a start. Fixes/contributions welcome. :) --- Diffs of the changes: (+43 -1) Index: llvm-www/www-index.html diff -u llvm-www/www-index.html:1.98 llvm-www/www-index.html:1.99 --- llvm-www/www-index.html:1.98 Fri Mar 19 22:51:08 2004 +++ llvm-www/www-index.html Fri Apr 16 11:02:26 2004 @@ -75,6 +75,49 @@ interested in contributing code to the LLVM infrastructure.

    +
    Strengths of the LLVM System
    + +

    +

      +
    1. LLVM uses a simple low-level language with strictly defined semantics.
    2. + +
    3. It includes front-ends for C, + C++, and Stacker (a forth-like language). Front-ends for + Java, Microsoft CLI, and O-Caml are in early development.
    4. + +
    5. It includes an aggressive optimizer, including scalar, interprocedural, + profile-driven, and some simple loop optimizations.
    6. + +
    7. It supports a life-long + compilation model, including link-time, install-time, run-time, and + offline optimization.
    8. + +
    9. It includes native code generators for X86 and Sparc (both of which work + as JIT or static compilers). LLVM can also compile to C code, for + portability. Other native backends are in development.
    10. + +
    11. LLVM has extensive documentation and has + hosted many projects of various sorts.
    12. + +
    13. Many third-party users have claimed that LLVM is easy to work with and + develop for. For example, the Stacker front-end was written in 4 days by someone who started + knowing nothing about LLVM. Additionally, LLVM has tools to make development easier.
    14. + +
    15. LLVM is under active development and is constantly being extended, + enhanced and improved. See the status updates on the left bar to see the rate + of development.
    16. + +
    17. LLVM is freely available under an OSI-approved "three-clause BSD" license.
    18. +
    +

    + + +
    Want to learn more?

    @@ -122,7 +165,6 @@ some of the optimizers.



    -
    Funding

    From brukman at cs.uiuc.edu Fri Apr 16 11:09:00 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Apr 16 11:09:00 2004 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/Parallel/ Message-ID: <200404161609.LAA16754@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/Parallel: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/test/Regression/Transforms/Parallel added to the repository --- Diffs of the changes: (+0 -0) From brukman at cs.uiuc.edu Fri Apr 16 11:11:02 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Apr 16 11:11:02 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Regression/Transforms/Parallel/20040416-ParallelCalls.ll Message-ID: <200404161610.LAA17682@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/Parallel: 20040416-ParallelCalls.ll added (r1.1.2.1) --- Log message: Test case for converting parallel calls into thread-based calls. --- Diffs of the changes: (+24 -0) Index: llvm/test/Regression/Transforms/Parallel/20040416-ParallelCalls.ll diff -c /dev/null llvm/test/Regression/Transforms/Parallel/20040416-ParallelCalls.ll:1.1.2.1 *** /dev/null Fri Apr 16 11:10:25 2004 --- llvm/test/Regression/Transforms/Parallel/20040416-ParallelCalls.ll Fri Apr 16 11:10:15 2004 *************** *** 0 **** --- 1,24 ---- + declare void %llvm.join(sbyte* %x) + + declare sbyte* %foo(sbyte* %f) + declare sbyte* %bar(sbyte* %b) + + int %main(int %argc, sbyte** %argv) { + entry: + br label %parallel + + parallel: + %x = pbr label %a, label %b + + a: + call sbyte* %foo(sbyte* null) + br label %exit + + b: + call sbyte* %bar(sbyte* null) + br label %exit + + exit: + call void %llvm.join(sbyte* %x) + ret int 0 + } From brukman at cs.uiuc.edu Fri Apr 16 11:12:02 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Apr 16 11:12:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Parallel/ Message-ID: <200404161611.LAA18557@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Parallel: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/lib/Transforms/Parallel added to the repository --> Using per-directory sticky tag `parallel' --- Diffs of the changes: (+0 -0) From brukman at cs.uiuc.edu Fri Apr 16 11:20:02 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Apr 16 11:20:02 2004 Subject: [llvm-commits] CVS: llvm/docs/Stacker.html Message-ID: <200404161620.LAA25276@zion.cs.uiuc.edu> Changes in directory llvm/docs: Stacker.html updated: 1.8 -> 1.9 --- Log message: * Fix capitalization of PICk * Wrap long lines to 80 cols --- Diffs of the changes: (+12 -12) Index: llvm/docs/Stacker.html diff -u llvm/docs/Stacker.html:1.8 llvm/docs/Stacker.html:1.9 --- llvm/docs/Stacker.html:1.8 Thu Mar 11 04:14:21 2004 +++ llvm/docs/Stacker.html Fri Apr 16 11:20:07 2004 @@ -1352,13 +1352,13 @@ by the compiler. That means you don't have to futz around with figuring out how to get the keyword recognized. It already is. The part of the compiler that you need to implement is the ROLL case in the -StackerCompiler::handle_word(int) method.

    See the implementations -of PICk and SELECT in the same method to get some hints about how to complete -this exercise.

    +StackerCompiler::handle_word(int) method.

    See the +implementations of PICK and SELECT in the same method to get some hints about +how to complete this exercise.

    Good luck!

    - +

    The initial implementation of Stacker has several deficiencies. If you're interested, here are some things that could be implemented better:

    @@ -1367,21 +1367,21 @@ program. Currently the stack is set to a fixed number which means programs with large numbers of definitions might fail.
  • Enhance to run on 64-bit platforms like SPARC. Right now the size of a - pointer on 64-bit machines will cause incorrect results because of the 32-bit - size of a stack element currently supported. This feature was not implemented - because LLVM needs a union type to be able to support the different sizes - correctly (portably and efficiently).
  • + pointer on 64-bit machines will cause incorrect results because of the + 32-bit size of a stack element currently supported. This feature was not + implemented because LLVM needs a union type to be able to support the + different sizes correctly (portably and efficiently).
  • Write an LLVM pass to optimize the use of the global stack. The code emitted currently is somewhat wasteful. It gets cleaned up a lot by existing passes but more could be done.
  • Add -O -O1 -O2 and -O3 optimization switches to the compiler driver to allow LLVM optimization without using "opt."
  • -
  • Make the compiler driver use the LLVM linking facilities (with IPO) before - depending on GCC to do the final link.
  • +
  • Make the compiler driver use the LLVM linking facilities (with IPO) + before depending on GCC to do the final link.
  • Clean up parsing. It doesn't handle errors very well.
  • Rearrange the StackerCompiler.cpp code to make better use of inserting instructions before a block's terminating instruction. I didn't figure this - technique out until I was nearly done with LLVM. As it is, its a bad example + technique out until I was nearly done with LLVM. As it is, its a bad example of how to insert instructions!
  • Provide for I/O to arbitrary files instead of just stdin/stdout.
  • Write additional built-in words; with inspiration from FORTH
  • @@ -1395,6 +1395,6 @@ +
    Last modified: $Date: 2004/04/16 16:20:07 $ From brukman at cs.uiuc.edu Fri Apr 16 11:25:03 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Apr 16 11:25:03 2004 Subject: [llvm-commits] [parallel] CVS: llvm/test/Regression/Transforms/Parallel/20040416-ParallelCalls.ll Message-ID: <200404161624.LAA00428@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/Parallel: 20040416-ParallelCalls.ll updated: 1.1.2.1 -> 1.1.2.2 --- Log message: Add a run line to test this regression. --- Diffs of the changes: (+2 -0) Index: llvm/test/Regression/Transforms/Parallel/20040416-ParallelCalls.ll diff -u llvm/test/Regression/Transforms/Parallel/20040416-ParallelCalls.ll:1.1.2.1 llvm/test/Regression/Transforms/Parallel/20040416-ParallelCalls.ll:1.1.2.2 --- llvm/test/Regression/Transforms/Parallel/20040416-ParallelCalls.ll:1.1.2.1 Fri Apr 16 11:10:15 2004 +++ llvm/test/Regression/Transforms/Parallel/20040416-ParallelCalls.ll Fri Apr 16 11:24:39 2004 @@ -1,3 +1,5 @@ +; RUN: llvm-as < %s | opt -pcall-thread | llvm-dis | grep __llvm_thread + declare void %llvm.join(sbyte* %x) declare sbyte* %foo(sbyte* %f) From gaeke at cs.uiuc.edu Fri Apr 16 11:29:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Apr 16 11:29:01 2004 Subject: [llvm-commits] CVS: llvm/include/Support/Statistic.h Message-ID: <200404161628.LAA00958@zion.cs.uiuc.edu> Changes in directory llvm/include/Support: Statistic.h updated: 1.10 -> 1.11 --- Log message: Switch to including for compatibility with gcc-3.0.x (Debian). --- Diffs of the changes: (+1 -1) Index: llvm/include/Support/Statistic.h diff -u llvm/include/Support/Statistic.h:1.10 llvm/include/Support/Statistic.h:1.11 --- llvm/include/Support/Statistic.h:1.10 Thu Feb 12 22:49:04 2004 +++ llvm/include/Support/Statistic.h Fri Apr 16 11:28:33 2004 @@ -24,7 +24,7 @@ #ifndef SUPPORT_STATISTIC_H #define SUPPORT_STATISTIC_H -#include +#include namespace llvm { From brukman at cs.uiuc.edu Fri Apr 16 11:35:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Apr 16 11:35:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/include/llvm/Analysis/ParallelInfo.h Message-ID: <200404161635.LAA01305@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: ParallelInfo.h updated: 1.1.2.2 -> 1.1.2.3 --- Log message: Accept a header BasicBlock in ParallelSeq constructor, various cleanups. --- Diffs of the changes: (+20 -20) Index: llvm/include/llvm/Analysis/ParallelInfo.h diff -u llvm/include/llvm/Analysis/ParallelInfo.h:1.1.2.2 llvm/include/llvm/Analysis/ParallelInfo.h:1.1.2.3 --- llvm/include/llvm/Analysis/ParallelInfo.h:1.1.2.2 Sun Feb 8 13:56:14 2004 +++ llvm/include/llvm/Analysis/ParallelInfo.h Fri Apr 16 11:35:12 2004 @@ -30,6 +30,7 @@ /// class ParallelRegion { ParallelSeq *parent; + std::vector children; std::vector Blocks; public: @@ -43,12 +44,14 @@ ParallelRegion(ParallelSeq *PS) : parent(PS) {} ParallelRegion(BasicBlock *BB) : parent(0) { Blocks.push_back(BB); } ParallelRegion() : parent(0) {} + ~ParallelRegion(); static ParallelRegion* discoverRegion(BasicBlock *pbrBlock, BasicBlock *begin, BasicBlock *end); void addBasicBlock(BasicBlock *BB) { Blocks.push_back(BB); } void removeBasicBlock(BasicBlock *BB); bool contains(const BasicBlock *BB); + void addChildSeq(ParallelSeq *PS); ParallelSeq *getParent() { return parent; } @@ -63,9 +66,8 @@ /// before the end of the function. /// class ParallelSeq { - ParallelSeq *ParentSeq; + ParallelRegion *parent; BasicBlock *SeqHeader; - std::vector ParaSubSeqs; // Other parallel sequences contained std::vector Regions; // Parallel code regions std::vector JoinBlocks; // Blocks containing "join", if any @@ -73,16 +75,16 @@ const ParallelSeq &operator=(const ParallelSeq &); // DO NOT IMPLEMENT public: + ParallelSeq(ParallelRegion *PR0, ParallelRegion *PR1, BasicBlock *SeqHd = 0) + : parent(0), SeqHeader(SeqHd) { + Regions.push_back(PR0); + Regions.push_back(PR1); + } + /// contains - Return true of the specified basic block is in this sequence /// bool contains(const BasicBlock *BB) const; - /// iterator/begin/end - Return the seqs contained entirely within this seq. - /// - typedef std::vector::const_iterator iterator; - iterator begin() const { return ParaSubSeqs.begin(); } - iterator end() const { return ParaSubSeqs.end(); } - /// region_iterator/region_begin/region_end - Return the regions contained /// within this parallel sequence. /// @@ -99,16 +101,13 @@ /// BasicBlock *getHeader() const { return SeqHeader; } + void setParent(ParallelRegion *PR) { parent = PR; } + void print(std::ostream &O, unsigned Depth = 0) const; void dump() const; private: friend class ParallelInfo; - inline ParallelSeq(ParallelRegion *PR0, ParallelRegion *PR1) - : ParentSeq(0), SeqHeader(0) { - Regions.push_back(PR0); - Regions.push_back(PR1); - } }; @@ -120,20 +119,21 @@ std::vector TopLevelSeqs; friend class ParallelSeq; - /// getAnalysisUsage - Requires dominator sets - /// - virtual void getAnalysisUsage(AnalysisUsage &AU) const; + void print(std::ostream &O) const; + + ParallelSeq* ConsiderParallelSeq(BasicBlock *BB, const DominatorSet &DS); + +public: /// runOnFunction - Calculate the parallel region information. /// virtual bool runOnFunction(Function &F); - void print(std::ostream &O) const; + /// getAnalysisUsage - Requires dominator sets + /// + virtual void getAnalysisUsage(AnalysisUsage &AU) const; void Calculate(const DominatorSet &DS); - ParallelSeq* ConsiderParallelSeq(BasicBlock *BB, const DominatorSet &DS); - -public: /// iterator/begin/end - The interface to the top-level parallel sequences in /// the current function. From brukman at cs.uiuc.edu Fri Apr 16 11:36:00 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Apr 16 11:36:00 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Analysis/ParallelInfo.cpp Message-ID: <200404161636.LAA01473@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ParallelInfo.cpp updated: 1.1.2.1 -> 1.1.2.2 --- Log message: * Allow pbr instructions to next within their regions * Pass in header BasicBlock to ParallelSeq --- Diffs of the changes: (+35 -16) Index: llvm/lib/Analysis/ParallelInfo.cpp diff -u llvm/lib/Analysis/ParallelInfo.cpp:1.1.2.1 llvm/lib/Analysis/ParallelInfo.cpp:1.1.2.2 --- llvm/lib/Analysis/ParallelInfo.cpp:1.1.2.1 Sun Feb 8 00:41:29 2004 +++ llvm/lib/Analysis/ParallelInfo.cpp Fri Apr 16 11:36:01 2004 @@ -15,8 +15,8 @@ #include "llvm/iOther.h" #include "llvm/iTerminators.h" -#include "llvm/Analysis/ParallelInfo.h" #include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/ParallelInfo.h" #include "llvm/Support/CFG.h" #include "Support/Debug.h" #include "Support/DepthFirstIterator.h" @@ -33,6 +33,17 @@ // ParallelRegion implementation // +ParallelRegion::~ParallelRegion() { + for (std::vector::iterator i = children.begin(), + e = children.end(); i != e; ++i) + (*i)->setParent(0); +} + +void ParallelRegion::addChildSeq(ParallelSeq *PS) { + children.push_back(PS); + PS->setParent(this); +} + bool ParallelRegion::contains(const BasicBlock *BB) { return std::find(Blocks.begin(), Blocks.end(), BB) != Blocks.end(); } @@ -79,11 +90,28 @@ Worklist.push_back(succ); } } else if (SwitchInst *SI = dyn_cast(TI)) { - assert(0 && "switch not handled within parallel region"); + for (unsigned i = 0, e = SI->getNumCases(); i != e; ++i) { + BasicBlock *succ = SI->getSuccessor(i); + DEBUG(std::cerr << "successor: " << succ->getName() << "\n"); + if (succ != pbrBlock && succ != end && !PR->contains(succ) && + std::find(Worklist.begin(), Worklist.end(), succ) == Worklist.end()) + Worklist.push_back(succ); + } } else if (ReturnInst *RI = dyn_cast(TI)) { assert(0 && "return not handled within parallel region"); } else if (ParaBrInst *PB = dyn_cast(TI)) { - assert(0 && "pbr not handled within parallel region"); + Value::use_iterator pbrUser = PB->use_begin(); + assert(pbrUser != PB->use_end() && "pbr not closed by join()?"); + CallInst *CI = dyn_cast(*pbrUser); + assert(CI && "result of pbr used in a non-call instr"); + assert(CI->getCalledFunction()->getName() == "llvm.join" && + "result of pbr used in a call to something besides `llvm.join'"); + BasicBlock *pbrBB = PB->getParent(), *joinBB = CI->getParent(); + ParallelSeq *PS = + new ParallelSeq(discoverRegion(pbrBB, PB->getSuccessor(0), joinBB), + discoverRegion(pbrBB, PB->getSuccessor(1), joinBB), + pbrBB); + PR->addChildSeq(PS); } else { assert(0 && " not handled within parallel region"); } @@ -128,7 +156,7 @@ // ParallelInfo implementation // -bool ParallelInfo::runOnFunction(Function &) { +bool ParallelInfo::runOnFunction(Function &F) { Calculate(getAnalysis()); return false; } @@ -144,17 +172,8 @@ ParallelSeq* ParallelInfo::ConsiderParallelSeq(BasicBlock *BB, const DominatorSet &DS) { - // if this block has a pbr - bool bbHasPbr = false; - ParaBrInst *PBr = 0; - for (BasicBlock::iterator i = BB->begin(), e = BB->end(); i != e; ++i) { - if ((PBr = dyn_cast(i))) { - bbHasPbr = true; - break; - } - } - - if (!bbHasPbr) return 0; + ParaBrInst *PBr = dyn_cast(BB->getTerminator()); + if (!PBr) return 0; // process each successor tree separately into regions, and combine them // into a parallel sequence @@ -176,7 +195,7 @@ DEBUG(std::cerr << "PR1: "; PR1->print(std::cerr); std::cerr << "\n";); // construct a parallel sequence - ParallelSeq *PS = new ParallelSeq(PR0, PR1); + ParallelSeq *PS = new ParallelSeq(PR0, PR1, BB); return PS; } From brukman at cs.uiuc.edu Fri Apr 16 11:56:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Apr 16 11:56:01 2004 Subject: [llvm-commits] CVS: llvm/docs/OpenProjects.html Message-ID: <200404161655.LAA08462@zion.cs.uiuc.edu> Changes in directory llvm/docs: OpenProjects.html updated: 1.23 -> 1.24 --- Log message: Add idea about a disassembler. --- Diffs of the changes: (+3 -1) Index: llvm/docs/OpenProjects.html diff -u llvm/docs/OpenProjects.html:1.23 llvm/docs/OpenProjects.html:1.24 --- llvm/docs/OpenProjects.html:1.23 Wed Apr 7 10:31:23 2004 +++ llvm/docs/OpenProjects.html Fri Apr 16 11:55:30 2004 @@ -315,6 +315,8 @@ candidate.
  • Write a new frontend for some other language (Java? OCaml? Forth?)
  • Write a new backend for a target (IA64? MIPS? MMIX?)
  • +
  • Write a disassembler for machine code that would use TableGen to output +MachineInstrs for transformations, optimizations, etc.
  • Random test vector generator: Use a C grammar to generate random C code; run it through llvm-gcc, then run a random set of passes on it using opt. Try to crash opt. When opt crashes, use bugpoint to reduce the test case and @@ -331,7 +333,7 @@
    Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2004/04/07 15:31:23 $ + Last modified: $Date: 2004/04/16 16:55:30 $ From gaeke at cs.uiuc.edu Fri Apr 16 12:14:01 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Apr 16 12:14:01 2004 Subject: [llvm-commits] CVS: llvm/autoconf/configure.ac Message-ID: <200404161713.MAA00314@zion.cs.uiuc.edu> Changes in directory llvm/autoconf: configure.ac updated: 1.85 -> 1.86 --- Log message: Refactor external benchmark checking stuff into one hairy macro-to-bind-them-all, called EXTERNAL_BENCHMARK(). --- Diffs of the changes: (+32 -69) Index: llvm/autoconf/configure.ac diff -u llvm/autoconf/configure.ac:1.85 llvm/autoconf/configure.ac:1.86 --- llvm/autoconf/configure.ac:1.85 Wed Apr 14 11:32:34 2004 +++ llvm/autoconf/configure.ac Fri Apr 16 12:13:33 2004 @@ -298,87 +298,50 @@ AC_SUBST(ENABLE_OPTIMIZED,[[ENABLE_OPTIMIZED=1]]) fi -dnl Spec 2000 Benchmarks -AC_ARG_ENABLE(spec2000,AC_HELP_STRING([--enable-spec2000],[Compile SPEC 2000 benchmarks (default is NO)]),,enableval=no) -if test ${enableval} = "no" -then - if test -d /home/vadve/shared/benchmarks/speccpu2000/benchspec - then - AC_SUBST(SPEC2000_ROOT,[/home/vadve/shared/benchmarks/speccpu2000/benchspec]) - AC_SUBST(USE_SPEC2000,[[USE_SPEC2000=1]]) - else - AC_SUBST(USE_SPEC2000,[[]]) - AC_SUBST(SPEC2000_ROOT,[]) - fi -else - if test ${enableval} = "" - then - AC_SUBST(SPEC2000_ROOT,[/home/vadve/shared/benchmarks/speccpu2000/benchspec]) - else - AC_SUBST(SPEC2000_ROOT,[${enableval}]) - fi - AC_SUBST(USE_SPEC2000,[[USE_SPEC2000=1]]) -fi - -dnl Spec 95 Benchmarks -AC_ARG_ENABLE(spec95,AC_HELP_STRING([--enable-spec95],[Compile SPEC 95 benchmarks (default is NO)]),,enableval=no) -if test ${enableval} = "no" -then - if test -d /home/vadve/shared/benchmarks/spec95/benchspec - then - AC_SUBST(SPEC95_ROOT,[/home/vadve/shared/benchmarks/spec95/benchspec]) - AC_SUBST(USE_SPEC95,[[USE_SPEC95=1]]) - else - AC_SUBST(USE_SPEC95,[[]]) - AC_SUBST(SPEC95_ROOT,[]) - fi -else - if test ${enableval} = "" - then - AC_SUBST(SPEC95_ROOT,[/home/vadve/shared/benchmarks/spec95/benchspec]) - else - AC_SUBST(SPEC95_ROOT,[${enableval}]) - fi - AC_SUBST(USE_SPEC95,[[USE_SPEC95=1]]) -fi - -dnl We can use POV-Ray as an external benchmark, if they have the sources. -AC_ARG_ENABLE(povray, - AC_HELP_STRING([--enable-povray=ARG], - [Use POV-Ray as a benchmark (srcs in DIR)]), - povray=$enableval, - povray=auto) -AC_MSG_CHECKING([for POV-Ray benchmark sources]) -case "$povray" in +AC_DEFUN(EXTERNAL_BENCHMARK, +[m4_define([allcapsname],translit($1,a-z,A-Z)) + AC_ARG_ENABLE($1, + AC_HELP_STRING([--enable-$1=ARG], + [Use $1 as a benchmark (srcs in DIR)]), + checkresult=$enableval, + checkresult=auto) +AC_MSG_CHECKING([for $1 benchmark sources]) +case "$checkresult" in auto|yes) - defaultdir=/home/vadve/shared/benchmarks/povray31 - if test -d $defaultdir + defaultdir=$2 + if test -d "$defaultdir" then - AC_SUBST(POVRAY_ROOT,[$defaultdir]) - AC_SUBST(USE_POVRAY,[[USE_POVRAY=1]]) - povray="yes, found in $defaultdir" + AC_SUBST(allcapsname()[_ROOT],[$defaultdir]) + AC_SUBST([USE_]allcapsname(),[USE_]allcapsname()=1) + checkresult="yes, found in $defaultdir" else - povray=no + checkresult=no fi ;; no) - AC_SUBST(POVRAY_ROOT,[]) - AC_SUBST(USE_POVRAY,[[]]) - povray=no + AC_SUBST(allcapsname()[_ROOT],[]) + AC_SUBST([USE_]allcapsname(),[]) + checkresult=no ;; -*) if test -d "$povray" +*) if test -d "$checkresult" then - AC_SUBST(POVRAY_ROOT,"$povray") - AC_SUBST(USE_POVRAY,[[USE_POVRAY=1]]) - povray="yes, in $povray" + AC_SUBST(allcapsname()[_ROOT],"$checkresult") + AC_SUBST([USE_]allcapsname(),[USE_]allcapsname()=1) + checkresult="yes, in $checkresult" else - AC_SUBST(POVRAY_ROOT,[]) - AC_SUBST(USE_POVRAY,[[]]) - povray="no, not found in $povray" + AC_SUBST(allcapsname()[_ROOT],[]) + AC_SUBST([USE_]allcapsname(),[]) + checkresult="no, not found in $checkresult" fi ;; esac -AC_MSG_RESULT($povray) +AC_MSG_RESULT($checkresult) +m4_undefine([allcapsname]) +]) + +EXTERNAL_BENCHMARK(spec95,/home/vadve/shared/benchmarks/spec95/benchspec) +EXTERNAL_BENCHMARK(spec2000,/home/vadve/shared/benchmarks/speccpu2000/benchspec) +EXTERNAL_BENCHMARK(povray,/home/vadve/shared/benchmarks/povray31) dnl Precompiled Bytecode Option AC_ARG_ENABLE(precompiled_bytecode,AC_HELP_STRING([--enable-precompiled_bytecode],[Use pre-compiled bytecode (default is NO)]),,enableval=no) From gaeke at cs.uiuc.edu Fri Apr 16 12:14:18 2004 From: gaeke at cs.uiuc.edu (Brian Gaeke) Date: Fri Apr 16 12:14:18 2004 Subject: [llvm-commits] CVS: llvm/configure Message-ID: <200404161713.MAA00384@zion.cs.uiuc.edu> Changes in directory llvm: configure updated: 1.87 -> 1.88 --- Log message: Regenerated using autoconf-2.57. --- Diffs of the changes: (+97 -66) Index: llvm/configure diff -u llvm/configure:1.87 llvm/configure:1.88 --- llvm/configure:1.87 Wed Apr 14 11:32:09 2004 +++ llvm/configure Fri Apr 16 12:13:44 2004 @@ -465,7 +465,7 @@ #endif" ac_unique_file=""Makefile.config.in"" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS subdirs INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os OS LLVMGCCDIR ARCH CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT CC CFLAGS ac_ct_CC CPP ifGNUmake LEX LEXLIB LEX_OUTPUT_ROOT YACC BISON EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL DOT ETAGS ETAGSFLAGS PYTHON QMTEST HAVE_PTHREAD_MUTEX_LOCK INCLUDE_SYS_TYPES_H INCLUDE_INTTYPES_H ENDIAN HAVE_STD_EXT_HASH_MAP HAVE_GNU_EXT_HASH_MAP HAVE_GLOBAL_HASH_MAP HAVE_STD_EXT_HASH_SET HAVE_GNU_EXT_HASH_SET HAVE_GLOBAL_HASH_S! ET HAVE_STD_ITERATOR HAVE_BI_ITERATOR HAVE_FWD_ITERATOR ALLOCA MMAP_FILE ENABLE_OPTIMIZED SPEC2000_ROOT USE_SPEC2000 SPEC95_ROOT USE_SPEC95 POVRAY_ROOT USE_POVRAY UPB DISABLE_LLC_DIFFS JIT LLVMCC1 LLVMCC1PLUS BCR PAPIDIR SHLIBEXT LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS subdirs INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os OS LLVMGCCDIR ARCH CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT CC CFLAGS ac_ct_CC CPP ifGNUmake LEX LEXLIB LEX_OUTPUT_ROOT YACC BISON EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL DOT ETAGS ETAGSFLAGS PYTHON QMTEST HAVE_PTHREAD_MUTEX_LOCK INCLUDE_SYS_TYPES_H INCLUDE_INTTYPES_H ENDIAN HAVE_STD_EXT_HASH_MAP HAVE_GNU_EXT_HASH_MAP HAVE_GLOBAL_HASH_MAP HAVE_STD_EXT_HASH_SET HAVE_GNU_EXT_HASH_SET HAVE_GLOBAL_HASH_S! ET HAVE_STD_ITERATOR HAVE_BI_ITERATOR HAVE_FWD_ITERATOR ALLOCA MMAP_FILE ENABLE_OPTIMIZED SPEC95_ROOT USE_SPEC95 SPEC2000_ROOT USE_SPEC2000 POVRAY_ROOT USE_POVRAY UPB DISABLE_LLC_DIFFS JIT LLVMCC1 LLVMCC1PLUS BCR PAPIDIR SHLIBEXT LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -1031,9 +1031,9 @@ optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --enable-optimized Compile with optimizations enabled (default is NO) - --enable-spec2000 Compile SPEC 2000 benchmarks (default is NO) - --enable-spec95 Compile SPEC 95 benchmarks (default is NO) - --enable-povray=ARG Use POV-Ray as a benchmark (srcs in DIR) + --enable-spec95=ARG Use spec95 as a benchmark (srcs in DIR) + --enable-spec2000=ARG Use spec2000 as a benchmark (srcs in DIR) + --enable-povray=ARG Use povray as a benchmark (srcs in DIR) --enable-precompiled_bytecode Use pre-compiled bytecode (default is NO) --enable-llc_diffs Enable LLC Diffs when testing (default is YES) @@ -21831,118 +21831,149 @@ fi -# Check whether --enable-spec2000 or --disable-spec2000 was given. -if test "${enable_spec2000+set}" = set; then - enableval="$enable_spec2000" + + + # Check whether --enable-spec95 or --disable-spec95 was given. +if test "${enable_spec95+set}" = set; then + enableval="$enable_spec95" + checkresult=$enableval else - enableval=no + checkresult=auto fi; -if test ${enableval} = "no" -then - if test -d /home/vadve/shared/benchmarks/speccpu2000/benchspec +echo "$as_me:$LINENO: checking for spec95 benchmark sources" >&5 +echo $ECHO_N "checking for spec95 benchmark sources... $ECHO_C" >&6 +case "$checkresult" in +auto|yes) + defaultdir=/home/vadve/shared/benchmarks/spec95/benchspec + if test -d "$defaultdir" then - SPEC2000_ROOT=/home/vadve/shared/benchmarks/speccpu2000/benchspec + SPEC95_ROOT=$defaultdir - USE_SPEC2000=USE_SPEC2000=1 + USE_SPEC95=USE_SPEC95=1 - else - USE_SPEC2000= + checkresult="yes, found in $defaultdir" + else + checkresult=no + fi + ;; +no) - fi -else - if test ${enableval} = "" - then - SPEC2000_ROOT=/home/vadve/shared/benchmarks/speccpu2000/benchspec + checkresult=no + ;; +*) if test -d "$checkresult" + then + SPEC95_ROOT="$checkresult" - else - SPEC2000_ROOT=${enableval} + USE_SPEC95=USE_SPEC95=1 - fi - USE_SPEC2000=USE_SPEC2000=1 + checkresult="yes, in $checkresult" + else -fi -# Check whether --enable-spec95 or --disable-spec95 was given. -if test "${enable_spec95+set}" = set; then - enableval="$enable_spec95" + checkresult="no, not found in $checkresult" + fi + ;; +esac +echo "$as_me:$LINENO: result: $checkresult" >&5 +echo "${ECHO_T}$checkresult" >&6 + + + # Check whether --enable-spec2000 or --disable-spec2000 was given. +if test "${enable_spec2000+set}" = set; then + enableval="$enable_spec2000" + checkresult=$enableval else - enableval=no + checkresult=auto fi; -if test ${enableval} = "no" -then - if test -d /home/vadve/shared/benchmarks/spec95/benchspec +echo "$as_me:$LINENO: checking for spec2000 benchmark sources" >&5 +echo $ECHO_N "checking for spec2000 benchmark sources... $ECHO_C" >&6 +case "$checkresult" in +auto|yes) + defaultdir=/home/vadve/shared/benchmarks/speccpu2000/benchspec + if test -d "$defaultdir" then - SPEC95_ROOT=/home/vadve/shared/benchmarks/spec95/benchspec + SPEC2000_ROOT=$defaultdir - USE_SPEC95=USE_SPEC95=1 + USE_SPEC2000=USE_SPEC2000=1 - else - USE_SPEC95= + checkresult="yes, found in $defaultdir" + else + checkresult=no + fi + ;; +no) - fi -else - if test ${enableval} = "" - then - SPEC95_ROOT=/home/vadve/shared/benchmarks/spec95/benchspec + checkresult=no + ;; +*) if test -d "$checkresult" + then + SPEC2000_ROOT="$checkresult" - else - SPEC95_ROOT=${enableval} + USE_SPEC2000=USE_SPEC2000=1 - fi - USE_SPEC95=USE_SPEC95=1 + checkresult="yes, in $checkresult" + else -fi -# Check whether --enable-povray or --disable-povray was given. + checkresult="no, not found in $checkresult" + fi + ;; +esac +echo "$as_me:$LINENO: result: $checkresult" >&5 +echo "${ECHO_T}$checkresult" >&6 + + + + # Check whether --enable-povray or --disable-povray was given. if test "${enable_povray+set}" = set; then enableval="$enable_povray" - povray=$enableval + checkresult=$enableval else - povray=auto + checkresult=auto fi; -echo "$as_me:$LINENO: checking for POV-Ray benchmark sources" >&5 -echo $ECHO_N "checking for POV-Ray benchmark sources... $ECHO_C" >&6 -case "$povray" in +echo "$as_me:$LINENO: checking for povray benchmark sources" >&5 +echo $ECHO_N "checking for povray benchmark sources... $ECHO_C" >&6 +case "$checkresult" in auto|yes) defaultdir=/home/vadve/shared/benchmarks/povray31 - if test -d $defaultdir + if test -d "$defaultdir" then POVRAY_ROOT=$defaultdir USE_POVRAY=USE_POVRAY=1 - povray="yes, found in $defaultdir" + checkresult="yes, found in $defaultdir" else - povray=no + checkresult=no fi ;; no) - USE_POVRAY= - povray=no + checkresult=no ;; -*) if test -d "$povray" +*) if test -d "$checkresult" then - POVRAY_ROOT="$povray" + POVRAY_ROOT="$checkresult" USE_POVRAY=USE_POVRAY=1 - povray="yes, in $povray" + checkresult="yes, in $checkresult" else - USE_POVRAY= - povray="no, not found in $povray" + checkresult="no, not found in $checkresult" fi ;; esac -echo "$as_me:$LINENO: result: $povray" >&5 -echo "${ECHO_T}$povray" >&6 +echo "$as_me:$LINENO: result: $checkresult" >&5 +echo "${ECHO_T}$checkresult" >&6 + + # Check whether --enable-precompiled_bytecode or --disable-precompiled_bytecode was given. if test "${enable_precompiled_bytecode+set}" = set; then @@ -22884,10 +22915,10 @@ s, at ALLOCA@,$ALLOCA,;t t s, at MMAP_FILE@,$MMAP_FILE,;t t s, at ENABLE_OPTIMIZED@,$ENABLE_OPTIMIZED,;t t -s, at SPEC2000_ROOT@,$SPEC2000_ROOT,;t t -s, at USE_SPEC2000@,$USE_SPEC2000,;t t s, at SPEC95_ROOT@,$SPEC95_ROOT,;t t s, at USE_SPEC95@,$USE_SPEC95,;t t +s, at SPEC2000_ROOT@,$SPEC2000_ROOT,;t t +s, at USE_SPEC2000@,$USE_SPEC2000,;t t s, at POVRAY_ROOT@,$POVRAY_ROOT,;t t s, at USE_POVRAY@,$USE_POVRAY,;t t s, at UPB@,$UPB,;t t From brukman at cs.uiuc.edu Fri Apr 16 12:14:32 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Apr 16 12:14:32 2004 Subject: [llvm-commits] CVS: llvm/runtime/libtrace/Makefile Message-ID: <200404161714.MAA00430@zion.cs.uiuc.edu> Changes in directory llvm/runtime/libtrace: Makefile updated: 1.8 -> 1.9 --- Log message: Fit comment into 80 cols. --- Diffs of the changes: (+1 -1) Index: llvm/runtime/libtrace/Makefile diff -u llvm/runtime/libtrace/Makefile:1.8 llvm/runtime/libtrace/Makefile:1.9 --- llvm/runtime/libtrace/Makefile:1.8 Mon Oct 20 17:28:48 2003 +++ llvm/runtime/libtrace/Makefile Fri Apr 16 12:13:52 2004 @@ -1,4 +1,4 @@ -##===- runtime/libtrace/Makefile ------------------------------*- Makefile -*-===## +##===- runtime/libtrace/Makefile ---------------------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # From brukman at cs.uiuc.edu Fri Apr 16 12:17:02 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Apr 16 12:17:02 2004 Subject: [llvm-commits] CVS: llvm/runtime/libthread/ Message-ID: <200404161716.MAA00827@zion.cs.uiuc.edu> Changes in directory llvm/runtime/libthread: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/runtime/libthread added to the repository --- Diffs of the changes: (+0 -0) From brukman at cs.uiuc.edu Fri Apr 16 12:18:02 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Apr 16 12:18:02 2004 Subject: [llvm-commits] [parallel] CVS: llvm/runtime/Makefile Message-ID: <200404161718.MAA01126@zion.cs.uiuc.edu> Changes in directory llvm/runtime: Makefile updated: 1.12.2.1 -> 1.12.2.2 --- Log message: * Merge with trunk * Add libthread to runtime libs --- Diffs of the changes: (+1 -1) Index: llvm/runtime/Makefile diff -u llvm/runtime/Makefile:1.12.2.1 llvm/runtime/Makefile:1.12.2.2 --- llvm/runtime/Makefile:1.12.2.1 Mon Mar 1 17:58:45 2004 +++ llvm/runtime/Makefile Fri Apr 16 12:17:55 2004 @@ -12,7 +12,7 @@ include $(LEVEL)/Makefile.config ifneq ($(wildcard $(LLVMGCCDIR)),) -PARALLEL_DIRS := GCCLibraries libdummy libprofile libtrace libpng zlib +PARALLEL_DIRS := GCCLibraries libdummy libprofile libtrace libthread else PARALLEL_DIRS := install all :: From brukman at cs.uiuc.edu Fri Apr 16 12:18:15 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Apr 16 12:18:15 2004 Subject: [llvm-commits] [parallel] CVS: llvm/runtime/libthread/Makefile threadlib.c threadlib.h Message-ID: <200404161717.MAA01027@zion.cs.uiuc.edu> Changes in directory llvm/runtime/libthread: Makefile added (r1.1.2.1) threadlib.c added (r1.1.2.1) threadlib.h added (r1.1.2.1) --- Log message: Add parallel thread start/join LLVM runtime library. --- Diffs of the changes: (+35 -0) Index: llvm/runtime/libthread/Makefile diff -c /dev/null llvm/runtime/libthread/Makefile:1.1.2.1 *** /dev/null Fri Apr 16 12:17:36 2004 --- llvm/runtime/libthread/Makefile Fri Apr 16 12:17:26 2004 *************** *** 0 **** --- 1,14 ---- + ##===- runtime/libthread/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 = ../.. + BYTECODE_LIBRARY=1 + LIBRARYNAME=thread + + include $(LEVEL)/Makefile.common + Index: llvm/runtime/libthread/threadlib.c diff -c /dev/null llvm/runtime/libthread/threadlib.c:1.1.2.1 *** /dev/null Fri Apr 16 12:17:36 2004 --- llvm/runtime/libthread/threadlib.c Fri Apr 16 12:17:26 2004 *************** *** 0 **** --- 1,13 ---- + #include "threadlib.h" + #include + + int __llvm_thread_start(void*(*fn)(void*), void* arg) { + pthread_t pt; + return pthread_create(&pt, 0, fn, arg); + } + + void __llvm_thread_join(int thread_id) { + pthread_join(thread_id, 0); + } + + Index: llvm/runtime/libthread/threadlib.h diff -c /dev/null llvm/runtime/libthread/threadlib.h:1.1.2.1 *** /dev/null Fri Apr 16 12:17:36 2004 --- llvm/runtime/libthread/threadlib.h Fri Apr 16 12:17:26 2004 *************** *** 0 **** --- 1,8 ---- + #ifndef THREADLIB_H + #define THREADLIB_H + + int __llvm_thread_start(void*(*fn)(void*), void* arg); + + void __llvm_thread_join(int thread_id); + + #endif From brukman at cs.uiuc.edu Fri Apr 16 12:24:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Apr 16 12:24:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/runtime/libthread/threadlib.c threadlib.h Message-ID: <200404161723.MAA01725@zion.cs.uiuc.edu> Changes in directory llvm/runtime/libthread: threadlib.c updated: 1.1.2.1 -> 1.1.2.2 threadlib.h updated: 1.1.2.1 -> 1.1.2.2 --- Log message: * Return a thread ID, not an error code, as per Chris' suggestion ;) * pthread_t is an unsigned long, not just a measly int --- Diffs of the changes: (+6 -5) Index: llvm/runtime/libthread/threadlib.c diff -u llvm/runtime/libthread/threadlib.c:1.1.2.1 llvm/runtime/libthread/threadlib.c:1.1.2.2 --- llvm/runtime/libthread/threadlib.c:1.1.2.1 Fri Apr 16 12:17:26 2004 +++ llvm/runtime/libthread/threadlib.c Fri Apr 16 12:23:24 2004 @@ -1,12 +1,13 @@ #include "threadlib.h" #include -int __llvm_thread_start(void*(*fn)(void*), void* arg) { +unsigned long __llvm_thread_start(void*(*fn)(void*), void* arg) { pthread_t pt; - return pthread_create(&pt, 0, fn, arg); + pthread_create(&pt, 0, fn, arg); + return pt; } -void __llvm_thread_join(int thread_id) { +void __llvm_thread_join(unsigned long thread_id) { pthread_join(thread_id, 0); } Index: llvm/runtime/libthread/threadlib.h diff -u llvm/runtime/libthread/threadlib.h:1.1.2.1 llvm/runtime/libthread/threadlib.h:1.1.2.2 --- llvm/runtime/libthread/threadlib.h:1.1.2.1 Fri Apr 16 12:17:26 2004 +++ llvm/runtime/libthread/threadlib.h Fri Apr 16 12:23:24 2004 @@ -1,8 +1,8 @@ #ifndef THREADLIB_H #define THREADLIB_H -int __llvm_thread_start(void*(*fn)(void*), void* arg); +unsigned long __llvm_thread_start(void*(*fn)(void*), void* arg); -void __llvm_thread_join(int thread_id); +void __llvm_thread_join(unsigned long thread_id); #endif From brukman at cs.uiuc.edu Fri Apr 16 12:28:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Apr 16 12:28:01 2004 Subject: [llvm-commits] [parallel] CVS: llvm/lib/Transforms/Parallel/Makefile ParallelCallsToThreads.cpp Message-ID: <200404161728.MAA09180@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Parallel: Makefile added (r1.1.2.1) ParallelCallsToThreads.cpp added (r1.1.2.1) --- Log message: First cut at converting calls in parallel regions to thread-based calls. --- Diffs of the changes: (+158 -0) Index: llvm/lib/Transforms/Parallel/Makefile diff -c /dev/null llvm/lib/Transforms/Parallel/Makefile:1.1.2.1 *** /dev/null Fri Apr 16 12:28:08 2004 --- llvm/lib/Transforms/Parallel/Makefile Fri Apr 16 12:27:58 2004 *************** *** 0 **** --- 1,16 ---- + ##===- lib/Transforms/Parallel/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 = ../../.. + PARALLEL_DIRS = + LIBRARYNAME = parallel + BUILD_ARCHIVE = 1 + SHARED_LIBRARY = 1 + + include $(LEVEL)/Makefile.common + Index: llvm/lib/Transforms/Parallel/ParallelCallsToThreads.cpp diff -c /dev/null llvm/lib/Transforms/Parallel/ParallelCallsToThreads.cpp:1.1.2.1 *** /dev/null Fri Apr 16 12:28:08 2004 --- llvm/lib/Transforms/Parallel/ParallelCallsToThreads.cpp Fri Apr 16 12:27:58 2004 *************** *** 0 **** --- 1,142 ---- + //===- PCallToThreads.cpp - Convert parallel calls to pthreads ------------===// + // + // 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. + // + //===----------------------------------------------------------------------===// + // + // Convert parallel function calls to threaded code. + // + //===----------------------------------------------------------------------===// + + #include "llvm/DerivedTypes.h" + #include "llvm/Module.h" + #include "llvm/iOther.h" + #include "llvm/iTerminators.h" + #include "llvm/Pass.h" + #include "llvm/Type.h" + #include "llvm/Analysis/ParallelInfo.h" + #include + using namespace llvm; + + namespace { + + /// PCallToThreads - + /// + /// FIXME: This should be a Pass, but Passes currently cannot require + /// FunctionPasses. + /// + struct PCallToThreads : public FunctionPass { + Type *startTy; + + public: + PCallToThreads() { + // void*(*start_routine)(void *) is the goal type + std::vector ArgTypes; + Type *VoidPtr = PointerType::get(Type::SByteTy); + ArgTypes.push_back(VoidPtr); + FunctionType *FT = FunctionType::get(VoidPtr, ArgTypes, false); + startTy = PointerType::get(FT); + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + } + + bool runOnFunction(Function &F); + + private: + Function* getFuncThreadStart(Module &M); + Function* getFuncThreadJoin(Module &M); + }; + + RegisterOpt + X("pcall-thread", "Convert parallel calls to thread-based code"); + + } // End anonymous namespace + + /// runOnFunction - + /// + bool PCallToThreads::runOnFunction(Function &F) { + bool Changed = false; + ParallelInfo &PI = getAnalysis(); + + // Convert parallel calls to pthread_create() invocations + for (ParallelInfo::iterator i = PI.begin(), e = PI.end(); i != e; ++i) { + ParallelSeq *PS = *i; + std::vector JoinValues; + for (ParallelSeq::region_iterator r = PS->region_begin(), + re = PS->region_end(); r != re; ++r) { + ParallelRegion *PR = *r; + std::vector RegionBlocks(PR->begin(), PR->end()); + + // Ensure that there is only one block in this region + assert(RegionBlocks.size() == 1 && "Parallel region has > 1 BB"); + + // Within the single block, the only code that should be there is a call + // and an unconditional branch to the join point + BasicBlock* BB = RegionBlocks[0]; + BasicBlock::iterator Instrs = BB->begin(); + CallInst *OldCall = dyn_cast(Instrs); + assert(OldCall && "First instr is not a call!"); + + // Replace call with __llvm_thread_create + Function *ThCreate = getFuncThreadStart(*F.getParent()); + assert(OldCall->getNumOperands() == 2 && + "Can only threadify calls with one argument!"); + + TerminatorInst *TI = BB->getTerminator(); + CastInst *funcPtr = new CastInst(OldCall->getOperand(0), startTy, + "cast_ptr", TI); + CastInst *funcVal = new CastInst(OldCall->getOperand(1), + PointerType::get(Type::SByteTy), + "cast_val", TI); + std::vector Args; + Args.push_back(funcPtr); + Args.push_back(funcVal); + CallInst *ThCreateCall = new CallInst(ThCreate, Args, "threadCall", TI); + + OldCall->getParent()->getInstList().erase(OldCall); + + Changed = true; + } + + // Convert llvm.join() intrinsic to __llvm_thread_join() calls + // Get join function call position/bb + ParaBrInst *Pbr = dyn_cast(PS->getHeader()->getTerminator()); + assert(Pbr && "Terminator of parallel sequence header is not a Pbr!"); + + std::vector Users(Pbr->use_begin(), Pbr->use_end()); + assert(Users.size() == 1 && "Must have unique user of Pbr"); + CallInst *JoinCall = cast(Users[0]); + assert(JoinCall && "Pbr result used in something other than call!"); + + Function *ThJoin = getFuncThreadJoin(*F.getParent()); + for (std::vector::iterator i = JoinValues.begin(), + e = JoinValues.end(); i != e; ++i) + CallInst *Join = new CallInst(ThJoin, *i, "join", JoinCall); + + if (JoinValues.size() > 0) + JoinCall->getParent()->getInstList().erase(JoinCall); + } + + return Changed; + } + + /// getFuncThreadStart - + /// + Function* PCallToThreads::getFuncThreadStart(Module &M) { + // int __llvm_thread_create(void*(*)(void*), void*); + return M.getOrInsertFunction("__llvm_thread_start", Type::IntTy, + startTy, PointerType::get(Type::SByteTy), 0); + } + + /// getFuncThreadJoin - + /// + Function* PCallToThreads::getFuncThreadJoin(Module &M) { + // void __llvm_thread_join(int); + return M.getOrInsertFunction("__llvm_thread_join", Type::VoidTy, Type::IntTy, + 0); + } From brukman at cs.uiuc.edu Fri Apr 16 12:37:01 2004 From: brukman at cs.uiuc.edu (Misha Brukman) Date: Fri Apr 16 12:37:01 2004 Subject: [llvm-commits] CVS: llvm/lib/VMCore/BasicBlock.cpp Message-ID: <200404161737.MAA25587@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: BasicBlock.cpp updated: 1.43 -> 1.44 --- Log message: Fix retriving parent Function. --- Diffs of the changes: (+1 -1) Index: llvm/lib/VMCore/BasicBlock.cpp diff -u llvm/lib/VMCore/BasicBlock.cpp:1.43 llvm/lib/VMCore/BasicBlock.cpp:1.44 --- llvm/lib/VMCore/BasicBlock.cpp:1.43 Fri Apr 16 10:47:21 2004 +++ llvm/lib/VMCore/BasicBlock.cpp Fri Apr 16 12:37:12 2004 @@ -81,7 +81,7 @@ BasicBlock::~BasicBlock() { - assert(Parent == 0 && "BasicBlock still linked into the program!"); + assert(getParent() == 0 && "BasicBlock still linked into the program!"); dropAllReferences(); InstList.clear(); } From lattner at cs.uiuc.edu Fri Apr 16 13:08:02 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Apr 16 13:08:02 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200404161808.NAA15335@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.190 -> 1.191 --- Log message: Fix some really nasty dominance bugs that were exposed by my patch to make the verifier more strict. This fixes building zlib --- Diffs of the changes: (+12 -29) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.190 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.191 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.190 Tue Apr 13 22:28:36 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri Apr 16 13:08:07 2004 @@ -397,30 +397,6 @@ // reassociate the expression from ((? op A) op B) to (? op (A op B)) if (ShouldApply) { BasicBlock *BB = Root.getParent(); - // All of the instructions have a single use and have no side-effects, - // because of this, we can pull them all into the current basic block. - if (LHSI->getParent() != BB) { - // Move all of the instructions from root to LHSI into the current - // block. - Instruction *TmpLHSI = cast(Root.getOperand(0)); - Instruction *LastUse = &Root; - while (TmpLHSI->getParent() == BB) { - LastUse = TmpLHSI; - TmpLHSI = cast(TmpLHSI->getOperand(0)); - } - - // Loop over all of the instructions in other blocks, moving them into - // the current one. - Value *TmpLHS = TmpLHSI; - do { - TmpLHSI = cast(TmpLHS); - // Remove from current block... - TmpLHSI->getParent()->getInstList().remove(TmpLHSI); - // Insert before the last instruction... - BB->getInstList().insert(LastUse, TmpLHSI); - TmpLHS = TmpLHSI->getOperand(0); - } while (TmpLHSI != LHSI); - } // Now all of the instructions are in the current basic block, go ahead // and perform the reassociation. @@ -431,20 +407,27 @@ // Make what used to be the LHS of the root be the user of the root... Value *ExtraOperand = TmpLHSI->getOperand(1); - if (&Root != TmpLHSI) - Root.replaceAllUsesWith(TmpLHSI); // Users now use TmpLHSI - else { + if (&Root == TmpLHSI) { Root.replaceAllUsesWith(Constant::getNullValue(TmpLHSI->getType())); return 0; } + Root.replaceAllUsesWith(TmpLHSI); // Users now use TmpLHSI TmpLHSI->setOperand(1, &Root); // TmpLHSI now uses the root - BB->getInstList().remove(&Root); // Remove root from the BB - BB->getInstList().insert(TmpLHSI, &Root); // Insert root before TmpLHSI + TmpLHSI->getParent()->getInstList().remove(TmpLHSI); + BasicBlock::iterator ARI = &Root; ++ARI; + BB->getInstList().insert(ARI, TmpLHSI); // Move TmpLHSI to after Root + ARI = Root; // Now propagate the ExtraOperand down the chain of instructions until we // get to LHSI. while (TmpLHSI != LHSI) { Instruction *NextLHSI = cast(TmpLHSI->getOperand(0)); + // Move the instruction to immediately before the chain we are + // constructing to avoid breaking dominance properties. + NextLHSI->getParent()->getInstList().remove(NextLHSI); + BB->getInstList().insert(ARI, NextLHSI); + ARI = NextLHSI; + Value *NextOp = NextLHSI->getOperand(1); NextLHSI->setOperand(1, ExtraOperand); TmpLHSI = NextLHSI; From lattner at cs.uiuc.edu Fri Apr 16 17:36:01 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Apr 16 17:36:01 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Utils/Local.cpp Message-ID: <200404162235.RAA13907@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Utils: Local.cpp updated: 1.20 -> 1.21 --- Log message: Add support for evaluation of exp/log/log10/pow --- Diffs of the changes: (+25 -1) Index: llvm/lib/Transforms/Utils/Local.cpp diff -u llvm/lib/Transforms/Utils/Local.cpp:1.20 llvm/lib/Transforms/Utils/Local.cpp:1.21 --- llvm/lib/Transforms/Utils/Local.cpp:1.20 Fri Apr 16 10:57:32 2004 +++ llvm/lib/Transforms/Utils/Local.cpp Fri Apr 16 17:35:33 2004 @@ -233,7 +233,8 @@ /// the specified function. bool llvm::canConstantFoldCallTo(Function *F) { const std::string &Name = F->getName(); - return Name == "sin" || Name == "cos" || Name == "tan" || Name == "sqrt"; + return Name == "sin" || Name == "cos" || Name == "tan" || Name == "sqrt" || + Name == "log" || Name == "log10" || Name == "exp" || Name == "pow"; } /// ConstantFoldCall - Attempt to constant fold a call to the specified function @@ -263,6 +264,29 @@ if (ConstantFP *CFP = dyn_cast(Operands[0])) if (CFP->getValue() >= 0) return ConstantFP::get(Ty, sqrt(CFP->getValue())); + } else if (Name == "exp") { + if (Operands.size() == 1) + if (ConstantFP *CFP = dyn_cast(Operands[0])) + return ConstantFP::get(Ty, exp(CFP->getValue())); + } else if (Name == "log") { + if (Operands.size() == 1) + if (ConstantFP *CFP = dyn_cast(Operands[0])) + if (CFP->getValue() > 0) + return ConstantFP::get(Ty, log(CFP->getValue())); + } else if (Name == "log10") { + if (Operands.size() == 1) + if (ConstantFP *CFP = dyn_cast(Operands[0])) + if (CFP->getValue() > 0) + return ConstantFP::get(Ty, log10(CFP->getValue())); + } else if (Name == "pow") { + if (Operands.size() == 2) + if (ConstantFP *Op1 = dyn_cast(Operands[0])) + if (ConstantFP *Op2 = dyn_cast(Operands[1])) { + errno = 0; + double V = pow(Op1->getValue(), Op2->getValue()); + if (errno == 0) + return ConstantFP::get(Ty, V); + } } return 0; } From alkis at cs.uiuc.edu Fri Apr 16 18:08:01 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri Apr 16 18:08:01 2004 Subject: [llvm-commits] CVS: llvm-java/include/llvm/Java/ClassFile.h Message-ID: <200404162307.SAA14461@zion.cs.uiuc.edu> Changes in directory llvm-java/include/llvm/Java: ClassFile.h updated: 1.2 -> 1.3 --- Log message: Fix several parsing bugs. Add ClassFileSemanticError exception class. Add operator<< for all classes. --- Diffs of the changes: (+42 -7) Index: llvm-java/include/llvm/Java/ClassFile.h diff -u llvm-java/include/llvm/Java/ClassFile.h:1.2 llvm-java/include/llvm/Java/ClassFile.h:1.3 --- llvm-java/include/llvm/Java/ClassFile.h:1.2 Thu Apr 15 23:03:45 2004 +++ llvm-java/include/llvm/Java/ClassFile.h Fri Apr 16 18:07:19 2004 @@ -96,6 +96,10 @@ ClassFile(std::istream& is); }; + inline std::ostream& operator<<(std::ostream& os, const ClassFile& c) { + return c.dump(os); + } + class Constant { protected: const ClassFile::ConstantPool& cPool_; @@ -123,9 +127,13 @@ virtual ~Constant(); - virtual std::ostream& dump(std::ostream& os) const; + virtual std::ostream& dump(std::ostream& os) const = 0; }; + inline std::ostream& operator<<(std::ostream& os, const Constant& c) { + return c.dump(os); + } + class ConstantClass : public Constant { uint16_t nameIdx_; public: @@ -133,6 +141,7 @@ const ConstantUtf8* getName() const { return (const ConstantUtf8*) cPool_[nameIdx_]; } + std::ostream& dump(std::ostream& os) const; }; class ConstantMemberRef : public Constant { @@ -148,6 +157,7 @@ const ConstantNameAndType* getNameAndType() const { return (const ConstantNameAndType*) cPool_[nameAndTypeIdx_]; } + std::ostream& dump(std::ostream& os) const; }; struct ConstantFieldRef : public ConstantMemberRef { @@ -173,6 +183,7 @@ const ConstantUtf8* getValue() const { return (const ConstantUtf8*) cPool_[stringIdx_]; } + std::ostream& dump(std::ostream& os) const; }; class ConstantInteger : public Constant { @@ -180,6 +191,7 @@ public: ConstantInteger(const ClassFile::ConstantPool& cp, std::istream& is); int32_t getValue() const { return value_; } + std::ostream& dump(std::ostream& os) const; }; class ConstantFloat : public Constant { @@ -187,6 +199,7 @@ public: ConstantFloat(const ClassFile::ConstantPool& cp, std::istream& is); float getValue() const { return value_; } + std::ostream& dump(std::ostream& os) const; }; class ConstantLong : public Constant { @@ -194,6 +207,7 @@ public: ConstantLong(const ClassFile::ConstantPool& cp, std::istream& is); int64_t getValue() const { return value_; } + std::ostream& dump(std::ostream& os) const; }; class ConstantDouble : public Constant { @@ -201,6 +215,7 @@ public: ConstantDouble(const ClassFile::ConstantPool& cp, std::istream& is); double getValue() const { return value_; } + std::ostream& dump(std::ostream& os) const; }; class ConstantNameAndType : public Constant { @@ -214,24 +229,24 @@ const ConstantUtf8* getDescriptor() const { return (const ConstantUtf8*) cPool_[descriptorIdx_]; } + std::ostream& dump(std::ostream& os) const; }; class ConstantUtf8 : public Constant { std::string utf8_; public: ConstantUtf8(const ClassFile::ConstantPool& cp, std::istream& is); + operator const std::string() const { return utf8_; } //const std::string& getUtf8() const { return utf8_; } + std::ostream& dump(std::ostream& os) const; }; class Field { - public: - typedef std::vector Attributes; - private: uint16_t accessFlags_; ConstantUtf8* name_; ConstantUtf8* descriptor_; - Attributes attrs_; + ClassFile::Attributes attributes_; Field(const ClassFile::ConstantPool& cp, std::istream& is); @@ -250,16 +265,20 @@ bool isTransient() const { return accessFlags_ & ACC_TRANSIENT; } ConstantUtf8* getName() const { return name_; } - ConstantUtf8* getDescriptorIdx() const { return descriptor_; } + ConstantUtf8* getDescriptor() const { return descriptor_; } std::ostream& dump(std::ostream& os) const; }; + inline std::ostream& operator<<(std::ostream& os, const Field& f) { + return f.dump(os); + } + class Method { uint16_t accessFlags_; ConstantUtf8* name_; ConstantUtf8* descriptor_; - ClassFile::Attributes attrs_; + ClassFile::Attributes attributes_; Method(const ClassFile::ConstantPool& cp, std::istream& is); @@ -285,6 +304,10 @@ std::ostream& dump(std::ostream& os) const; }; + inline std::ostream& operator<<(std::ostream& os, const Method& m) { + return m.dump(os); + } + class Attribute { ConstantUtf8* name_; @@ -300,11 +323,23 @@ std::ostream& dump(std::ostream& os) const; }; + inline std::ostream& operator<<(std::ostream& os, const Attribute& a) { + return a.dump(os); + } + class ClassFileParseError : public std::exception { std::string msg_; public: explicit ClassFileParseError(const std::string& msg) : msg_(msg) { } virtual ~ClassFileParseError() throw(); + virtual const char* what() const throw() { return msg_.c_str(); } + }; + + class ClassFileSemanticError : public std::exception { + std::string msg_; + public: + explicit ClassFileSemanticError(const std::string& msg) : msg_(msg) { } + virtual ~ClassFileSemanticError() throw(); virtual const char* what() const throw() { return msg_.c_str(); } }; From alkis at cs.uiuc.edu Fri Apr 16 18:08:15 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri Apr 16 18:08:15 2004 Subject: [llvm-commits] CVS: llvm-java/lib/ClassFile/ClassFile.cpp Message-ID: <200404162307.SAA14456@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/ClassFile: ClassFile.cpp updated: 1.1 -> 1.2 --- Log message: Fix several parsing bugs. Add ClassFileSemanticError exception class. Add operator<< for all classes. --- Diffs of the changes: (+223 -144) Index: llvm-java/lib/ClassFile/ClassFile.cpp diff -u llvm-java/lib/ClassFile/ClassFile.cpp:1.1 llvm-java/lib/ClassFile/ClassFile.cpp:1.2 --- llvm-java/lib/ClassFile/ClassFile.cpp:1.1 Thu Apr 15 16:00:50 2004 +++ llvm-java/lib/ClassFile/ClassFile.cpp Fri Apr 16 18:07:19 2004 @@ -25,11 +25,6 @@ // Utility functions namespace { - char bool2cross(bool v) - { - return v ? 'x' : ' '; - } - uint8_t readU1(std::istream& is) { char val; if (!is.get(val)) @@ -38,11 +33,13 @@ } uint16_t readU2(std::istream& is) { - return (readU1(is) << 8) | readU1(is); + uint16_t val = readU1(is); + return (val << 8) | readU1(is); } uint32_t readU4(std::istream& is) { - return (readU2(is) << 16) | readU2(is); + uint32_t val = readU2(is); + return (val << 16) | readU2(is); } uint64_t readU8(std::istream& is) { @@ -62,7 +59,130 @@ return tmp.out; } -}; + void readConstantPool(ClassFile::ConstantPool& cp, std::istream& is) + { + assert(cp.empty() && "Should not call with a non-empty constant pool"); + uint16_t count = readU2(is); + cp.reserve(count); + cp.push_back(NULL); + --count; + while (count--) + cp.push_back(Constant::readConstant(cp, is)); + } + + void readInterfaces(ClassFile::Interfaces& i, + const ClassFile::ConstantPool& cp, + std::istream& is) + { + assert(i.empty() && + "Should not call with a non-empty interfaces vector"); + uint16_t count = readU2(is); + i.reserve(count); + while (count--) { + ConstantClass* c = dynamic_cast(cp[readU2(is)]); + if (!c) throw "FIXME: give better error message"; + i.push_back(c); + } + } + + void readFields(ClassFile::Fields& f, + const ClassFile::ConstantPool& cp, + std::istream& is) + { + assert(f.empty() && "Should not call with a non-empty fields vector"); + uint16_t count = readU2(is); + f.reserve(count); + while(count--) + f.push_back(Field::readField(cp, is)); + } + + void readMethods(ClassFile::Methods& m, + const ClassFile::ConstantPool& cp, + std::istream& is) + { + assert(m.empty() && "Should not call with a non-empty methods vector"); + uint16_t count = readU2(is); + m.reserve(count); + while(count--) + m.push_back(Method::readMethod(cp, is)); + } + + void readAttributes(ClassFile::Attributes& a, + const ClassFile::ConstantPool& cp, + std::istream& is) + { + assert(a.empty() && + "Should not call with a non-empty attributes vector"); + uint16_t count = readU2(is); + a.reserve(count); + while(count--) + a.push_back(Attribute::readAttribute(cp, is)); + } + + template + std::ostream& dumpCollection(Container& c, + const char* const name, + std::ostream& os) { + os << '\n' << name << "s:\n"; + for (typename Container::const_iterator + i = c.begin(), e = c.end(); i != e; ++i) + (*i)->dump(os << name << ' ') << '\n'; + return os; + } + +} + +//===----------------------------------------------------------------------===// +// ClassFile implementation +ClassFile* ClassFile::readClassFile(std::istream& is) +{ + if (readU1(is) != 0xCA) throw ClassFileParseError("bad magic"); + if (readU1(is) != 0xFE) throw ClassFileParseError("bad magic"); + if (readU1(is) != 0xBA) throw ClassFileParseError("bad magic"); + if (readU1(is) != 0xBE) throw ClassFileParseError("bad magic"); + + return new ClassFile(is); +} + +ClassFile::ClassFile(std::istream& is) +{ + minorV_ = readU2(is); + majorV_ = readU2(is); + readConstantPool(cPool_, is); + accessFlags_ = readU2(is); + thisClass_ = dynamic_cast(cPool_[readU2(is)]); + if (!thisClass_) + throw ClassFileSemanticError( + "Representation of this class is not of type ConstantClass"); + superClass_ = dynamic_cast(cPool_[readU2(is)]); + if (!superClass_) + throw ClassFileSemanticError( + "Representation of super class is not of type ConstantClass"); + readInterfaces(interfaces_, cPool_, is); + readFields(fields_, cPool_, is); + readMethods(methods_, cPool_, is); + readAttributes(attributes_, cPool_, is); +} + +std::ostream& ClassFile::dump(std::ostream& os) const +{ + os << "Minor version: " << getMinorVersion() << '\n' + << "Major version: " << getMajorVersion() << "\n\n" + << "class " << *getThisClass() << " (" << *getSuperClass() << ")\n" + << "Flags:"; + if (isPublic()) os << " public"; + if (isFinal()) os << " final"; + if (isSuper()) os << " super"; + if (isInterface()) os << " interface"; + if (isAbstract()) os << " abstract"; + + dumpCollection(interfaces_, "Interface", os); + dumpCollection(fields_, "Field", os); + dumpCollection(methods_, "Method", os); + dumpCollection(attributes_, "Attribute", os); + + return os; +} //===----------------------------------------------------------------------===// // ClassFileParseError implementation @@ -72,6 +192,13 @@ } //===----------------------------------------------------------------------===// +// ClassFileSemanticError implementation +ClassFileSemanticError::~ClassFileSemanticError() throw() +{ + +} + +//===----------------------------------------------------------------------===// // Constant implementation Constant* Constant::readConstant(const ClassFile::ConstantPool& cp, std::istream& is) @@ -112,12 +239,6 @@ } -std::ostream& Constant::dump(std::ostream& os) const -{ - // FIXME - return os; -} - ConstantMemberRef::ConstantMemberRef(const ClassFile::ConstantPool&cp, std::istream& is) : Constant(cp), @@ -127,6 +248,11 @@ } +std::ostream& ConstantMemberRef::dump(std::ostream& os) const +{ + return os << *getNameAndType() << '(' << *getClass() << ')'; +} + ConstantClass::ConstantClass(const ClassFile::ConstantPool& cp, std::istream& is) : Constant(cp), @@ -135,6 +261,11 @@ } +std::ostream& ConstantClass::dump(std::ostream& os) const +{ + return os << *getName(); +} + ConstantString::ConstantString(const ClassFile::ConstantPool& cp, std::istream& is) : Constant(cp), @@ -143,6 +274,11 @@ } +std::ostream& ConstantString::dump(std::ostream& os) const +{ + return os << "string " << *getValue(); +} + ConstantInteger::ConstantInteger(const ClassFile::ConstantPool& cp, std::istream& is) : Constant(cp), @@ -151,6 +287,11 @@ } +std::ostream& ConstantInteger::dump(std::ostream& os) const +{ + return os << value_; +} + ConstantFloat::ConstantFloat(const ClassFile::ConstantPool& cp, std::istream& is) : Constant(cp), @@ -159,6 +300,11 @@ } +std::ostream& ConstantFloat::dump(std::ostream& os) const +{ + return os << value_; +} + ConstantLong::ConstantLong(const ClassFile::ConstantPool& cp, std::istream& is) : Constant(cp), @@ -167,6 +313,11 @@ } +std::ostream& ConstantLong::dump(std::ostream& os) const +{ + return os << value_; +} + ConstantDouble::ConstantDouble(const ClassFile::ConstantPool& cp, std::istream& is) : Constant(cp), @@ -175,6 +326,11 @@ } +std::ostream& ConstantDouble::dump(std::ostream& os) const +{ + return os << value_; +} + ConstantNameAndType::ConstantNameAndType(const ClassFile::ConstantPool& cp, std::istream& is) : Constant(cp), @@ -184,6 +340,11 @@ } +std::ostream& ConstantNameAndType::dump(std::ostream& os) const +{ + return os << *getDescriptor() << ' ' << *getName(); +} + ConstantUtf8::ConstantUtf8(const ClassFile::ConstantPool& cp, std::istream& is) : Constant(cp) @@ -194,19 +355,40 @@ utf8_ = std::string(buf, length); } +std::ostream& ConstantUtf8::dump(std::ostream& os) const +{ + return os << utf8_; +} + //===----------------------------------------------------------------------===// // Field implementation Field::Field(const ClassFile::ConstantPool& cp, std::istream& is) { accessFlags_ = readU2(is); - name_ = dynamic_cast(cp[readU2(is)]); - if (!name_) throw "FIXME: better error message"; + if (!name_) + throw ClassFileSemanticError( + "Representation of field name is not of type ConstantUtf8"); descriptor_ = dynamic_cast(cp[readU2(is)]); + if (!descriptor_) + throw ClassFileSemanticError( + "Representation of field descriptor is not of type ConstantUtf8"); + readAttributes(attributes_, cp, is); } std::ostream& Field::dump(std::ostream& os) const { - // FIXME + os << *getName() << ' ' << *getDescriptor() << '\n' + << "Flags:"; + if (isPublic()) os << " public"; + if (isPrivate()) os << " private"; + if (isProtected()) os << " protected"; + if (isStatic()) os << " static"; + if (isFinal()) os << " final"; + if (isVolatile()) os << " volatile"; + if (isTransient()) os << " transient"; + + dumpCollection(attributes_, "Attribute", os); + return os; } @@ -216,13 +398,31 @@ { accessFlags_ = readU2(is); name_ = dynamic_cast(cp[readU2(is)]); - if (!name_) throw "FIXME: better error message"; + if (!name_) + throw ClassFileSemanticError( + "Representation of method name is not of type ConstantUtf8"); descriptor_ = dynamic_cast(cp[readU2(is)]); + if (!descriptor_) + throw ClassFileSemanticError( + "Representation of method descriptor is not of type ConstantUtf8"); + readAttributes(attributes_, cp, is); } std::ostream& Method::dump(std::ostream& os) const { - // FIXME + os << *getName() << ' ' << *getDescriptor() << '\n' + << "Flags:"; + if (isPublic()) os << " public"; + if (isPrivate()) os << " private"; + if (isProtected()) os << " protected"; + if (isStatic()) os << " static"; + if (isFinal()) os << " final"; + if (isSynchronized()) os << " synchronized"; + if (isNative()) os << " native"; + if (isStrict()) os << " strict"; + + dumpCollection(attributes_, "Attribute", os); + return os; } @@ -231,7 +431,9 @@ Attribute::Attribute(const ClassFile::ConstantPool& cp, std::istream& is) { name_ = dynamic_cast(cp[readU2(is)]); - if (!name_) throw "FIXME: better error message"; + if (!name_) + throw ClassFileSemanticError( + "Representation of attribute name is not of type ConstantUtf8"); uint32_t length = readU4(is); is.ignore(length); } @@ -244,129 +446,6 @@ std::ostream& Attribute::dump(std::ostream& os) const { - // FIXME - return os; -} - -//===----------------------------------------------------------------------===// -// ClassFile implementation -ClassFile* ClassFile::readClassFile(std::istream& is) -{ - if (readU1(is) != 0xCA) throw ClassFileParseError("bad magic"); - if (readU1(is) != 0xFE) throw ClassFileParseError("bad magic"); - if (readU1(is) != 0xBA) throw ClassFileParseError("bad magic"); - if (readU1(is) != 0xBE) throw ClassFileParseError("bad magic"); - - return new ClassFile(is); -} - -namespace { - - void readConstantPool(ClassFile::ConstantPool& cp, std::istream& is) - { - assert(cp.empty() && "Should not call with a non-empty constant pool"); - uint16_t count = readU2(is) - 1; - cp.reserve(count); - while (count--) - cp.push_back(Constant::readConstant(cp, is)); - } - - void readInterfaces(ClassFile::Interfaces& i, - const ClassFile::ConstantPool& cp, - std::istream& is) - { - assert(i.empty() && - "Should not call with a non-empty interfaces vector"); - uint16_t count = readU2(is); - i.reserve(count); - while (count--) { - ConstantClass* c = dynamic_cast(cp[readU2(is)]); - if (!c) throw "FIXME: give better error message"; - i.push_back(c); - } - } - - void readFields(ClassFile::Fields& f, - const ClassFile::ConstantPool& cp, - std::istream& is) - { - assert(f.empty() && "Should not call with a non-empty fields vector"); - uint16_t count = readU2(is); - f.reserve(count); - while(count--) - f.push_back(Field::readField(cp, is)); - } - - void readMethods(ClassFile::Methods& m, - const ClassFile::ConstantPool& cp, - std::istream& is) - { - assert(m.empty() && "Should not call with a non-empty methods vector"); - uint16_t count = readU2(is); - m.reserve(count); - while(count--) - m.push_back(Method::readMethod(cp, is)); - } - - void readAttributes(ClassFile::Attributes& a, - const ClassFile::ConstantPool& cp, - std::istream& is) - { - assert(a.empty() && - "Should not call with a non-empty attributes vector"); - uint16_t count = readU2(is); - a.reserve(count); - while(count--) - a.push_back(Attribute::readAttribute(cp, is)); - } - -} - -ClassFile::ClassFile(std::istream& is) -{ - minorV_ = readU2(is); - majorV_ = readU2(is); - readConstantPool(cPool_, is); - accessFlags_ = readU2(is); - thisClass_ = dynamic_cast(cPool_[readU2(is)]); - if (!thisClass_) throw "FIXME: better error message"; - superClass_ = dynamic_cast(cPool_[readU2(is)]); - if (!superClass_) throw "FIXME: better error message"; - readInterfaces(interfaces_, cPool_, is); - readFields(fields_, cPool_, is); - readMethods(methods_, cPool_, is); - readAttributes(attributes_, cPool_, is); -} - -std::ostream& ClassFile::dump(std::ostream& os) const -{ - os << "Minor version: " << getMinorVersion() << '\n' - << "Major version: " << getMajorVersion() << '\n' - << "Access flags (PFSIA): " - << bool2cross(isPublic()) - << bool2cross(isFinal()) - - << bool2cross(isSuper()) - << bool2cross(isInterface()) - << bool2cross(isAbstract()) << '\n' - << "This class: " << getThisClass() << '\n' - << "Super class: " << getSuperClass() << '\n'; - - for (Interfaces::const_iterator - i = interfaces_.begin(), e = interfaces_.end(); i != e; ++i) - (*i)->dump(os); - - for (Fields::const_iterator - i = fields_.begin(), e = fields_.end(); i != e; ++i) - (*i)->dump(os); - - for (Methods::const_iterator - i = methods_.begin(), e = methods_.end(); i != e; ++i) - (*i)->dump(os); - - for (Attributes::const_iterator - i = attributes_.begin(), e = attributes_.end(); i != e; ++i) - (*i)->dump(os); - + os << *getName() << '\n'; return os; } From alkis at cs.uiuc.edu Fri Apr 16 19:55:01 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Fri Apr 16 19:55:01 2004 Subject: [llvm-commits] CVS: llvm-java/tools/classdump/classdump.cpp Message-ID: <200404170055.TAA14861@zion.cs.uiuc.edu> Changes in directory llvm-java/tools/classdump: classdump.cpp updated: 1.2 -> 1.3 --- Log message: Delete classfile representation after dumping it to std::cout. --- Diffs of the changes: (+1 -0) Index: llvm-java/tools/classdump/classdump.cpp diff -u llvm-java/tools/classdump/classdump.cpp:1.2 llvm-java/tools/classdump/classdump.cpp:1.3 --- llvm-java/tools/classdump/classdump.cpp:1.2 Thu Apr 15 23:03:45 2004 +++ llvm-java/tools/classdump/classdump.cpp Fri Apr 16 19:55:08 2004 @@ -24,6 +24,7 @@ try { Java::ClassFile* cf = Java::ClassFile::readClassFile(std::cin); cf->dump(std::cout); + delete cf; } catch (std::exception& e) { std::cerr << e.what() << '\n'; From alkis at cs.uiuc.edu Sat Apr 17 11:19:07 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat Apr 17 11:19:07 2004 Subject: [llvm-commits] CVS: llvm-java/include/llvm/Java/ClassFile.h Message-ID: <200404170752.CAA25918@zion.cs.uiuc.edu> Changes in directory llvm-java/include/llvm/Java: ClassFile.h updated: 1.3 -> 1.4 --- Log message: Fix memory leaks. Add ConstantValue and Code attributes. --- Diffs of the changes: (+89 -8) Index: llvm-java/include/llvm/Java/ClassFile.h diff -u llvm-java/include/llvm/Java/ClassFile.h:1.3 llvm-java/include/llvm/Java/ClassFile.h:1.4 --- llvm-java/include/llvm/Java/ClassFile.h:1.3 Fri Apr 16 18:07:19 2004 +++ llvm-java/include/llvm/Java/ClassFile.h Sat Apr 17 02:52:16 2004 @@ -57,6 +57,8 @@ public: static ClassFile* readClassFile(std::istream& is); + ~ClassFile(); + uint16_t getMinorVersion() const { return minorV_; } uint16_t getMajorVersion() const { return majorV_; } @@ -71,13 +73,13 @@ const ConstantClass* getThisClass() const { return thisClass_; } const ConstantClass* getSuperClass() const { return superClass_; } - const Interfaces& getInterfaces() const; + const Interfaces& getInterfaces() const { return interfaces_; } - const Fields& getFields() const; + const Fields& getFields() const { return fields_; } - const Methods& getMethods() const; + const Methods& getMethods() const { return methods_; } - const Attributes& getAttributes() const; + const Attributes& getAttributes() const { return attributes_; } std::ostream& dump(std::ostream& os) const; @@ -236,8 +238,9 @@ std::string utf8_; public: ConstantUtf8(const ClassFile::ConstantPool& cp, std::istream& is); - operator const std::string() const { return utf8_; } - //const std::string& getUtf8() const { return utf8_; } + operator const char* const() const { return utf8_.c_str(); } + operator const std::string&() const { return utf8_; } + std::ostream& dump(std::ostream& os) const; }; @@ -256,6 +259,8 @@ return new Field(cp, is); } + ~Field(); + bool isPublic() const { return accessFlags_ & ACC_PUBLIC; } bool isPrivate() const { return accessFlags_ & ACC_PRIVATE; } bool isProtected() const { return accessFlags_ & ACC_PROTECTED; } @@ -266,6 +271,9 @@ ConstantUtf8* getName() const { return name_; } ConstantUtf8* getDescriptor() const { return descriptor_; } + const ClassFile::Attributes& getAttributes() const { + return attributes_; + } std::ostream& dump(std::ostream& os) const; }; @@ -288,6 +296,8 @@ return new Method(cp, is); } + ~Method(); + bool isPublic() const { return accessFlags_ & ACC_PUBLIC; } bool isPrivate() const { return accessFlags_ & ACC_PRIVATE; } bool isProtected() const { return accessFlags_ & ACC_PROTECTED; } @@ -300,6 +310,9 @@ ConstantUtf8* getName() const { return name_; } ConstantUtf8* getDescriptor() const { return descriptor_; } + const ClassFile::Attributes& getAttributes() const { + return attributes_; + } std::ostream& dump(std::ostream& os) const; }; @@ -312,19 +325,87 @@ ConstantUtf8* name_; protected: - Attribute(const ClassFile::ConstantPool& cp, std::istream& is); + Attribute(ConstantUtf8* name, + const ClassFile::ConstantPool& cp, + std::istream& is); public: static Attribute* readAttribute(const ClassFile::ConstantPool& cp, std::istream& is); + virtual ~Attribute(); + ConstantUtf8* getName() const { return name_; } - std::ostream& dump(std::ostream& os) const; + virtual std::ostream& dump(std::ostream& os) const; }; inline std::ostream& operator<<(std::ostream& os, const Attribute& a) { return a.dump(os); + } + + class AttributeConstantValue : public Attribute { + Constant* value_; + public: + AttributeConstantValue(ConstantUtf8* name, + const ClassFile::ConstantPool& cp, + std::istream& is); + + Constant* getValue() const { return value_; } + + std::ostream& dump(std::ostream& os) const; + }; + + class AttributeCode : public Attribute { + public: + class Exception { + uint16_t startPc_; + uint16_t endPc_; + uint16_t handlerPc_; + ConstantClass* catchType_; + + public: + Exception(const ClassFile::ConstantPool& cp, std::istream& is); + + uint16_t getStartPc() const { return startPc_; } + uint16_t getEndPc() const { return endPc_; } + uint16_t getHandlerPc() const { return handlerPc_; } + ConstantClass* getCatchType() const { return catchType_; } + + std::ostream& dump(std::ostream& os) const; + }; + + typedef std::vector Exceptions; + + private: + uint16_t maxStack_; + uint16_t maxLocals_; + uint32_t codeSize_; + char* code_; + Exceptions exceptions_; + ClassFile::Attributes attributes_; + + public: + AttributeCode(ConstantUtf8* name, + const ClassFile::ConstantPool& cp, + std::istream& is); + ~AttributeCode(); + uint16_t getMaxStack() const { return maxStack_; } + uint16_t getMaxLocals() const { return maxLocals_; } + const char* getCode() const { return code_; } + uint32_t getCodeSize() const { return codeSize_; } + const Exceptions& getExceptions() const { return exceptions_; } + const ClassFile::Attributes& getAttributes() const { + return attributes_; + } + + std::ostream& dump(std::ostream& os) const; + + }; + + inline std::ostream& operator<<(std::ostream& os, + const AttributeCode::Exception& e) { + return e.dump(os); } class ClassFileParseError : public std::exception { From alkis at cs.uiuc.edu Sat Apr 17 11:19:19 2004 From: alkis at cs.uiuc.edu (Alkis Evlogimenos) Date: Sat Apr 17 11:19:19 2004 Subject: [llvm-commits] CVS: llvm-java/lib/ClassFile/ClassFile.cpp Message-ID: <200404170752.CAA25915@zion.cs.uiuc.edu> Changes in directory llvm-java/lib/ClassFile: ClassFile.cpp updated: 1.2 -> 1.3 --- Log message: Fix memory leaks. Add ConstantValue and Code attributes. --- Diffs of the changes: (+135 -12) Index: llvm-java/lib/ClassFile/ClassFile.cpp diff -u llvm-java/lib/ClassFile/ClassFile.cpp:1.2 llvm-java/lib/ClassFile/ClassFile.cpp:1.3 --- llvm-java/lib/ClassFile/ClassFile.cpp:1.2 Fri Apr 16 18:07:19 2004 +++ llvm-java/lib/ClassFile/ClassFile.cpp Sat Apr 17 02:52:15 2004 @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include +#include #include #include @@ -126,7 +127,10 @@ os << '\n' << name << "s:\n"; for (typename Container::const_iterator i = c.begin(), e = c.end(); i != e; ++i) - (*i)->dump(os << name << ' ') << '\n'; + if (*i) + (*i)->dump(os << name << ' ') << '\n'; + else + os << name << " NULL\n"; return os; } @@ -164,6 +168,14 @@ readAttributes(attributes_, cPool_, is); } +ClassFile::~ClassFile() +{ + for_each(cPool_.begin(), cPool_.end(), deleter); + for_each(fields_.begin(), fields_.end(), deleter); + for_each(methods_.begin(), methods_.end(), deleter); + for_each(attributes_.begin(), attributes_.end(), deleter); +} + std::ostream& ClassFile::dump(std::ostream& os) const { os << "Minor version: " << getMinorVersion() << '\n' @@ -351,8 +363,11 @@ { uint16_t length = readU2(is); char buf[length]; - is.read(buf, length); - utf8_ = std::string(buf, length); + std::streamsize s = is.rdbuf()->sgetn(buf, length); + if (s != length) + throw ClassFileParseError( + "Could not read string constant from input stream"); + utf8_.assign(buf, length); } std::ostream& ConstantUtf8::dump(std::ostream& os) const @@ -375,6 +390,11 @@ readAttributes(attributes_, cp, is); } +Field::~Field() +{ + for_each(attributes_.begin(), attributes_.end(), deleter); +} + std::ostream& Field::dump(std::ostream& os) const { os << *getName() << ' ' << *getDescriptor() << '\n' @@ -408,6 +428,11 @@ readAttributes(attributes_, cp, is); } +Method::~Method() +{ + for_each(attributes_.begin(), attributes_.end(), deleter); +} + std::ostream& Method::dump(std::ostream& os) const { os << *getName() << ' ' << *getDescriptor() << '\n' @@ -428,24 +453,122 @@ //===----------------------------------------------------------------------===// // Attribute implementation -Attribute::Attribute(const ClassFile::ConstantPool& cp, std::istream& is) +Attribute* Attribute::readAttribute(const ClassFile::ConstantPool& cp, + std::istream& is) { - name_ = dynamic_cast(cp[readU2(is)]); - if (!name_) + ConstantUtf8* name = dynamic_cast(cp[readU2(is)]); + if (!name) throw ClassFileSemanticError( "Representation of attribute name is not of type ConstantUtf8"); - uint32_t length = readU4(is); - is.ignore(length); + + if (strcmp(*name, "ConstantValue") == 0) + return new AttributeConstantValue(name, cp, is); + else if (strcmp(*name, "Code") == 0) + return new AttributeCode(name, cp, is); + else { + uint32_t length = readU4(is); + is.ignore(length); + return new Attribute(name, cp, is); + } } -Attribute* Attribute::readAttribute(const ClassFile::ConstantPool& cp, - std::istream& is) +Attribute::Attribute(ConstantUtf8* name, + const ClassFile::ConstantPool& cp, + std::istream& is) + : name_(name) +{ + +} + +Attribute::~Attribute() { - return new Attribute(cp, is); + } std::ostream& Attribute::dump(std::ostream& os) const { - os << *getName() << '\n'; + return os << *getName(); +} + +//===----------------------------------------------------------------------===// +// AttributeConstantValue implementation +AttributeConstantValue::AttributeConstantValue( + ConstantUtf8* name, + const ClassFile::ConstantPool& cp, + std::istream& is) + : Attribute(name, cp, is) +{ + uint32_t length = readU4(is); + if (length != 2) + throw ClassFileSemanticError( + "Length of AttributeConstantValue is not 2"); + value_ = cp[readU2(is)]; +} + +std::ostream& AttributeConstantValue::dump(std::ostream& os) const +{ + return Attribute::dump(os) << ": " << *value_; +} + +//===----------------------------------------------------------------------===// +// Attribute code +AttributeCode::AttributeCode(ConstantUtf8* name, + const ClassFile::ConstantPool& cp, + std::istream& is) + : Attribute(name, cp, is) +{ + uint32_t length = readU4(is); + maxStack_ = readU2(is); + maxLocals_ = readU2(is); + codeSize_ = readU4(is); + code_ = new char[codeSize_]; + std::streamsize s = is.rdbuf()->sgetn(code_, codeSize_); + if (s != (std::streamsize) codeSize_) + throw ClassFileParseError( + "Could not read code from input stream"); + uint16_t exceptCount = readU2(is); + exceptions_.reserve(exceptCount); + while (exceptCount--) + exceptions_.push_back(new Exception(cp, is)); + readAttributes(attributes_, cp, is); +} + +AttributeCode::~AttributeCode() +{ + delete[] code_; + for_each(exceptions_.begin(), exceptions_.end(), deleter); + for_each(attributes_.begin(), attributes_.end(), deleter); +} + +std::ostream& AttributeCode::dump(std::ostream& os) const +{ + Attribute::dump(os) + << '\n' + << "Max stack: " << maxStack_ << '\n' + << "Max locals: " << maxLocals_ << '\n' + << "Code size: " << codeSize_ << '\n'; + dumpCollection(exceptions_, "Exception", os); + dumpCollection(attributes_, "Attribute", os); + return os; +} + +AttributeCode::Exception::Exception(const ClassFile::ConstantPool& cp, + std::istream& is) +{ + startPc_ = readU2(is); + endPc_ = readU2(is); + handlerPc_ = readU2(is); + catchType_ = dynamic_cast(cp[readU2(is)]); + if (!catchType_) + throw ClassFileSemanticError( + "Representation of catch type is not of type ConstantClass"); +} + +std::ostream& AttributeCode::Exception::dump(std::ostream& os) const +{ + return os << *getCatchType() << '\n' + << "Start PC: " << startPc_ << '\n' + << "End PC: " << endPc_ << '\n' + << "Handler PC: " << handlerPc_; } From lattner at cs.uiuc.edu Sat Apr 17 18:36:08 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Apr 17 18:36:08 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <200404171808.NAA19556@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: IndVarSimplify.cpp updated: 1.56 -> 1.57 --- Log message: Even if there are not any induction variables in the loop, if we can compute the trip count for the loop, insert one so that we can canonicalize the exit condition. --- Diffs of the changes: (+11 -1) Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp diff -u llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.56 llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.57 --- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.56 Fri Apr 16 01:03:17 2004 +++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Sat Apr 17 13:08:33 2004 @@ -368,7 +368,17 @@ // If there are no induction variables in the loop, there is nothing more to // do. - if (IndVars.empty()) return; + if (IndVars.empty()) { + // Actually, if we know how many times the loop iterates, lets insert a + // canonical induction variable to help subsequent passes. + if (!isa(IterationCount)) { + ScalarEvolutionRewriter Rewriter(*SE, *LI); + Rewriter.GetOrInsertCanonicalInductionVariable(L, + IterationCount->getType()); + LinearFunctionTestReplace(L, IterationCount, Rewriter); + } + return; + } // Compute the type of the largest recurrence expression. // From lattner at cs.uiuc.edu Sat Apr 17 18:36:19 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Apr 17 18:36:19 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200404171816.NAA20116@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.191 -> 1.192 --- Log message: Fix a HUGE pessimization on X86. The indvars pass was taking this (familiar) function: int _strlen(const char *str) { int len = 0; while (*str++) len++; return len; } And transforming it to use a ulong induction variable, because the type of the pointer index was left as a constant long. This is obviously very bad. The fix is to shrink long constants in getelementptr instructions to intptr_t, making the indvars pass insert a uint induction variable, which is much more efficient. Here's the before code for this function: int %_strlen(sbyte* %str) { entry: %tmp.13 = load sbyte* %str ; [#uses=1] %tmp.24 = seteq sbyte %tmp.13, 0 ; [#uses=1] br bool %tmp.24, label %loopexit, label %no_exit no_exit: ; preds = %entry, %no_exit *** %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ] ; [#uses=2] *** %indvar = phi ulong [ %indvar.next, %no_exit ], [ 0, %entry ] ; [#uses=2] %indvar1 = cast ulong %indvar to uint ; [#uses=1] %inc.02.sum = add uint %indvar1, 1 ; [#uses=1] %inc.0.0 = getelementptr sbyte* %str, uint %inc.02.sum ; [#uses=1] %tmp.1 = load sbyte* %inc.0.0 ; [#uses=1] %tmp.2 = seteq sbyte %tmp.1, 0 ; [#uses=1] %indvar.next = add ulong %indvar, 1 ; [#uses=1] %indvar.next = add uint %indvar, 1 ; [#uses=1] br bool %tmp.2, label %loopexit.loopexit, label %no_exit loopexit.loopexit: ; preds = %no_exit %indvar = cast uint %indvar to int ; [#uses=1] %inc.1 = add int %indvar, 1 ; [#uses=1] ret int %inc.1 loopexit: ; preds = %entry ret int 0 } Here's the after code: int %_strlen(sbyte* %str) { entry: %inc.02 = getelementptr sbyte* %str, uint 1 ; [#uses=1] %tmp.13 = load sbyte* %str ; [#uses=1] %tmp.24 = seteq sbyte %tmp.13, 0 ; [#uses=1] br bool %tmp.24, label %loopexit, label %no_exit no_exit: ; preds = %entry, %no_exit *** %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ] ; [#uses=3] %indvar = cast uint %indvar to int ; [#uses=1] %inc.0.0 = getelementptr sbyte* %inc.02, uint %indvar ; [#uses=1] %inc.1 = add int %indvar, 1 ; [#uses=1] %tmp.1 = load sbyte* %inc.0.0 ; [#uses=1] %tmp.2 = seteq sbyte %tmp.1, 0 ; [#uses=1] %indvar.next = add uint %indvar, 1 ; [#uses=1] br bool %tmp.2, label %loopexit, label %no_exit loopexit: ; preds = %entry, %no_exit %len.0.1 = phi int [ 0, %entry ], [ %inc.1, %no_exit ] ; [#uses=1] ret int %len.0.1 } --- Diffs of the changes: (+4 -1) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.191 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.192 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.191 Fri Apr 16 13:08:07 2004 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sat Apr 17 13:16:10 2004 @@ -2580,7 +2580,10 @@ // obvious. Value *Op = GEP.getOperand(i); if (Op->getType()->getPrimitiveSize() > TD->getPointerSize()) - if (!isa(Op)) { + if (Constant *C = dyn_cast(Op)) { + GEP.setOperand(i, ConstantExpr::getCast(C, TD->getIntPtrType())); + MadeChange = true; + } else { Op = InsertNewInstBefore(new CastInst(Op, TD->getIntPtrType(), Op->getName()), GEP); GEP.setOperand(i, Op); From lattner at cs.uiuc.edu Sat Apr 17 18:36:32 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Apr 17 18:36:32 2004 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ScalarEvolution.cpp Message-ID: <200404171836.NAA21706@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ScalarEvolution.cpp updated: 1.12 -> 1.13 --- Log message: Add the ability to compute trip counts that are only controlled by constants even if the loop is using expressions that we can't compute as a closed-form. This allows us to calculate that this function always returns 55: int test() { double X; int Count = 0; for (X = 100; X > 1; X = sqrt(X), ++Count) /*empty*/; return Count; } And allows us to compute trip counts for loops like: int h = 1; do h = 3 * h + 1; while (h <= 256); (which occurs in bzip2), and for this function, which occurs after inlining and other optimizations: int popcount() { int x = 666; int result = 0; while (x != 0) { result = result + (x & 0x1); x = x >> 1; } return result; } We still cannot compute the exit values of result or h in the two loops above, which means we cannot delete the loop, but we are getting closer. Being able to compute a constant trip count for these two loops will allow us to unroll them completely though. --- Diffs of the changes: (+174 -5) Index: llvm/lib/Analysis/ScalarEvolution.cpp diff -u llvm/lib/Analysis/ScalarEvolution.cpp:1.12 llvm/lib/Analysis/ScalarEvolution.cpp:1.13 --- llvm/lib/Analysis/ScalarEvolution.cpp:1.12 Fri Apr 16 10:57:32 2004 +++ llvm/lib/Analysis/ScalarEvolution.cpp Sat Apr 17 13:36:24 2004 @@ -72,9 +72,11 @@ #include "llvm/Analysis/LoopInfo.h" #include "llvm/Assembly/Writer.h" #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Support/CFG.h" #include "llvm/Support/ConstantRange.h" #include "llvm/Support/InstIterator.h" +#include "Support/CommandLine.h" #include "Support/Statistic.h" #include using namespace llvm; @@ -92,6 +94,14 @@ Statistic<> NumTripCountsNotComputed("scalar-evolution", "Number of loops without predictable loop counts"); + Statistic<> + NumBruteForceTripCountsComputed("scalar-evolution", + "Number of loops with trip counts computed by force"); + + cl::opt + MaxBruteForceIterations("scalar-evolution-max-iterations", cl::ReallyHidden, + cl::desc("Maximum number of iterations SCEV will symbolically execute a constant derived loop"), + cl::init(100)); } //===----------------------------------------------------------------------===// @@ -1170,6 +1180,14 @@ /// will iterate. SCEVHandle ComputeIterationCount(const Loop *L); + /// ComputeIterationCountExhaustively - If the trip is known to execute a + /// constant number of times (the condition evolves only from constants), + /// try to evaluate a few iterations of the loop until we get the exit + /// condition gets a value of ExitWhen (true or false). If we cannot + /// evaluate the trip count of the loop, return UnknownValue. + SCEVHandle ComputeIterationCountExhaustively(const Loop *L, Value *Cond, + bool ExitWhen); + /// HowFarToZero - Return the number of times a backedge comparing the /// specified value to zero will execute. If not computable, return /// UnknownValue @@ -1444,7 +1462,9 @@ if (ExitBr == 0) return UnknownValue; assert(ExitBr->isConditional() && "If unconditional, it can't be in loop!"); SetCondInst *ExitCond = dyn_cast(ExitBr->getCondition()); - if (ExitCond == 0) return UnknownValue; + if (ExitCond == 0) // Not a setcc + return ComputeIterationCountExhaustively(L, ExitBr->getCondition(), + ExitBr->getSuccessor(0) == ExitBlock); SCEVHandle LHS = getSCEV(ExitCond->getOperand(0)); SCEVHandle RHS = getSCEV(ExitCond->getOperand(1)); @@ -1505,13 +1525,17 @@ switch (Cond) { case Instruction::SetNE: // while (X != Y) // Convert to: while (X-Y != 0) - if (LHS->getType()->isInteger()) - return HowFarToZero(getMinusSCEV(LHS, RHS), L); + if (LHS->getType()->isInteger()) { + SCEVHandle TC = HowFarToZero(getMinusSCEV(LHS, RHS), L); + if (!isa(TC)) return TC; + } break; case Instruction::SetEQ: // Convert to: while (X-Y == 0) // while (X == Y) - if (LHS->getType()->isInteger()) - return HowFarToNonZero(getMinusSCEV(LHS, RHS), L); + if (LHS->getType()->isInteger()) { + SCEVHandle TC = HowFarToNonZero(getMinusSCEV(LHS, RHS), L); + if (!isa(TC)) return TC; + } break; default: #if 0 @@ -1523,6 +1547,151 @@ #endif break; } + + return ComputeIterationCountExhaustively(L, ExitCond, + ExitBr->getSuccessor(0) == ExitBlock); +} + + +/// getConstantEvolvingPHI - Given an LLVM value and a loop, return a PHI node +/// in the loop that V is derived from. We allow arbitrary operations along the +/// way, but the operands of an operation must either be constants or a value +/// derived from a constant PHI. If this expression does not fit with these +/// constraints, return null. +static PHINode *getConstantEvolvingPHI(Value *V, const Loop *L) { + // If this is not an instruction, or if this is an instruction outside of the + // loop, it can't be derived from a loop PHI. + Instruction *I = dyn_cast(V); + if (I == 0 || !L->contains(I->getParent())) return 0; + + if (PHINode *PN = dyn_cast(I)) + if (L->getHeader() == I->getParent()) + return PN; + else + // We don't currently keep track of the control flow needed to evaluate + // PHIs, so we cannot handle PHIs inside of loops. + return 0; + + // If this is a call, and we have no hope of constant folding, bail early. + if (CallInst *CI = dyn_cast(I)) { + if (!CI->getCalledFunction() || + !canConstantFoldCallTo(CI->getCalledFunction())) + return 0; + } else if (InvokeInst *II = dyn_cast(I)) + return 0; + + // Otherwise, we can evaluate this instruction if all of its operands but one + // are constant, and if the remaining one is derived from a constant evolving + // PHI. + unsigned Op = 0, e = I->getNumOperands(); + while (Op != e && (isa(I->getOperand(Op)) || + isa(I->getOperand(Op)))) + ++Op; // Skip over all constant operands + + if (Op == e) return 0; // No non-constants? Should be folded! + + // Found the first non-constant operand. + unsigned NonConstantOp = Op; + + // Okay, all of the rest must be constants now. + for (++Op; Op != e; ++Op) + if (!(isa(I->getOperand(Op)) || + isa(I->getOperand(Op)))) + return 0; // Too many non-constant operands! + + // This is a expression evolving from a constant PHI if the non-constant + // portion is! + return getConstantEvolvingPHI(I->getOperand(NonConstantOp), L); +} + +/// EvaluateExpression - Given an expression that passes the +/// getConstantEvolvingPHI predicate, evaluate its value assuming the PHI node +/// in the loop has the value PHIVal. If we can't fold this expression for some +/// reason, return null. +static Constant *EvaluateExpression(Value *V, Constant *PHIVal) { + if (isa(V)) return PHIVal; + if (Constant *C = dyn_cast(V)) return C; + if (GlobalValue *GV = dyn_cast(V)) + return ConstantPointerRef::get(GV); + Instruction *I = cast(V); + + std::vector Operands; + Operands.resize(I->getNumOperands()); + + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { + Operands[i] = EvaluateExpression(I->getOperand(i), PHIVal); + if (Operands[i] == 0) return 0; + } + + if (isa(I) || isa(I)) + return ConstantExpr::get(I->getOpcode(), Operands[0], Operands[1]); + + switch (I->getOpcode()) { + case Instruction::Cast: + return ConstantExpr::getCast(Operands[0], I->getType()); + case Instruction::Select: + return ConstantExpr::getSelect(Operands[0], Operands[1], Operands[2]); + case Instruction::Call: + if (ConstantPointerRef *CPR = dyn_cast(Operands[0])) { + Operands.erase(Operands.begin()); + return ConstantFoldCall(cast(CPR->getValue()), Operands); + } + + return 0; + case Instruction::GetElementPtr: + Constant *Base = Operands[0]; + Operands.erase(Operands.begin()); + return ConstantExpr::getGetElementPtr(Base, Operands); + } + return 0; +} + + +/// ComputeIterationCountExhaustively - If the trip is known to execute a +/// constant number of times (the condition evolves only from constants), +/// try to evaluate a few iterations of the loop until we get the exit +/// condition gets a value of ExitWhen (true or false). If we cannot +/// evaluate the trip count of the loop, return UnknownValue. +SCEVHandle ScalarEvolutionsImpl:: +ComputeIterationCountExhaustively(const Loop *L, Value *Cond, bool ExitWhen) { + PHINode *PN = getConstantEvolvingPHI(Cond, L); + if (PN == 0) return UnknownValue; + + // Since the loop is canonicalized, the PHI node must have two entries. One + // entry must be a constant (coming in from outside of the loop), and the + // second must be derived from the same PHI. + bool SecondIsBackedge = L->contains(PN->getIncomingBlock(1)); + Constant *StartCST = + dyn_cast(PN->getIncomingValue(!SecondIsBackedge)); + if (StartCST == 0) return UnknownValue; // Must be a constant. + + Value *BEValue = PN->getIncomingValue(SecondIsBackedge); + PHINode *PN2 = getConstantEvolvingPHI(BEValue, L); + if (PN2 != PN) return UnknownValue; // Not derived from same PHI. + + // Okay, we find a PHI node that defines the trip count of this loop. Execute + // the loop symbolically to determine when the condition gets a value of + // "ExitWhen". + unsigned IterationNum = 0; + unsigned MaxIterations = MaxBruteForceIterations; // Limit analysis. + for (Constant *PHIVal = StartCST; + IterationNum != MaxIterations; ++IterationNum) { + ConstantBool *CondVal = + dyn_cast_or_null(EvaluateExpression(Cond, PHIVal)); + if (!CondVal) return UnknownValue; // Couldn't symbolically evaluate. + if (CondVal->getValue() == ExitWhen) { + ++NumBruteForceTripCountsComputed; + return SCEVConstant::get(ConstantUInt::get(Type::UIntTy, IterationNum)); + } + + // Otherwise, compute the value of the PHI node for the next iteration. + Constant *Next = EvaluateExpression(BEValue, PHIVal); + if (Next == 0 || Next == PHIVal) + return UnknownValue; // Couldn't evaluate or not making progress... + PHIVal = Next; + } + + // Too many iterations were needed to evaluate. return UnknownValue; } From lattner at cs.uiuc.edu Sat Apr 17 18:36:43 2004 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Apr 17 18:36:43 2004 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Message-ID: <200404171844.NAA23711@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: IndVarSimplify.cpp updated: 1.57 -> 1.58 --- Log message: If the loop executes a constant number of times, try a bit harder to replace exit values. --- Diffs of the changes: (+5 -2) Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp diff -u llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.57 llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.58 --- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.57 Sat Apr 17 13:08:33 2004 +++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp Sat Apr 17 13:44:09 2004 @@ -276,6 +276,8 @@ BasicBlock::iterator InsertPt = BlockToInsertInto->begin(); while (isa(InsertPt)) ++InsertPt; + bool HasConstantItCount = isa(SE->getIterationCount(L)); + std::set InstructionsToDelete; for (unsigned i = 0, e = L->getBlocks().size(); i != e; ++i) @@ -284,7 +286,8 @@ for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) if (I->getType()->isInteger()) { // Is an integer instruction SCEVHandle SH = SE->getSCEV(I); - if (SH->hasComputableLoopEvolution(L)) { // Varies predictably + if (SH->hasComputableLoopEvolution(L) || // Varies predictably + HasConstantItCount) { // Find out if this predictably varying value is actually used // outside of the loop. "extra" as opposed to "intra". std::vector ExtraLoopUsers; @@ -296,7 +299,7 @@ // Okay, this instruction has a user outside of the current loop // and varies predictably in this loop. Evaluate the value it // contains when the loop exits, and insert code for it. - SCEVHandle ExitValue = SE->getSCEVAtScope(I,L->getParentLoop()); + SCEVHandle ExitValue = SE->getSCEVAtScope(I, L->getParentLoop()); if (!isa(ExitValue)) { Changed = true; ++NumReplaced; From vadve at cs.uiuc.edu Sat Apr 17 18:37:28 2004 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Apr 17 18:37:28 2004 Subject: [llvm-commits] CVS: llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html Message-ID: <200404172006.PAA01709@psmith.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2003-04-29-DataStructureAnalysisTR.html updated: 1.4 -> 1.5 --- Log message: Replaced old DSA paper with version from Nov. 15, 2003. --- Diffs of the changes: (+4 -2) Index: llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html diff -u llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html:1.4 llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html:1.5 --- llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html:1.4 Tue Oct 21 19:26:00 2003 +++ llvm-www/pubs/2003-04-29-DataStructureAnalysisTR.html Sat Apr 17 15:05:56 2004 @@ -46,9 +46,11 @@

    Download:

    From vadve at cs.uiuc.edu Sat Apr 17 18:37:40 2004 From: vadve at cs.uiuc.edu (Vikram Adve) Date: Sat Apr 17 18:37:40 2004 Subject: [llvm-commits] CVS: llvm-www/pubs/2003-11-15-DataStructureAnalysisTR.pdf 2003-11-15-DataStructureAnalysisTR.ps Message-ID: <200404172007.PAA01737@psmith.cs.uiuc.edu> Changes in directory llvm-www/pubs: 2003-11-15-DataStructureAnalysisTR.pdf added (r1.1) 2003-11-15-DataStructureAnalysisTR.ps added (r1.1) --- Log message: Updated versions of DSA paper. --- Diffs of the changes: (+12645 -0) Index: llvm-www/pubs/2003-11-15-DataStructureAnalysisTR.pdf Index: llvm-www/pubs/2003-11-15-DataStructureAnalysisTR.ps diff -c /dev/null llvm-www/pubs/2003-11-15-DataStructureAnalysisTR.ps:1.1 *** /dev/null Sat Apr 17 15:07:45 2004 --- llvm-www/pubs/2003-11-15-DataStructureAnalysisTR.ps Sat Apr 17 15:07:35 2004 *************** *** 0 **** --- 1,12645 ---- + %!PS-Adobe-2.0 + %%Creator: dvips(k) 5.90a Copyright 2002 Radical Eye Software + %%Title: paper.dvi + %%Pages: 10 + %%PageOrder: Ascend + %%BoundingBox: 0 0 612 792 + %%DocumentFonts: Helvetica-Bold Helvetica CMSY9 CMTT9 Times-Bold CMR9 + %%+ CMTI9 CMBX9 CMR6 CMMI9 CMR7 CMBX7 CMSY7 CMMI7 CMTI7 CMR8 CMMI6 + %%+ CMCSC10 CMTT8 Times-Italic CMSY5 CMR5 CMMI5 CMBX8 CMSY8 CMTI8 + %%EndComments + %DVIPSWebPage: (www.radicaleye.com) + %DVIPSCommandLine: dvips -t letter -o paper.ps paper.dvi + %DVIPSParameters: dpi=1200, compressed + %DVIPSSource: TeX output 2003.11.15:2234 + %%BeginProcSet: texc.pro + %! + /TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S + N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 + mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 + 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ + landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize + mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ + matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round + exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ + statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] + N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin + /FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array + /BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 + array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N + df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A + definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get + }B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} + B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr + 1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 + 1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx + 0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx + sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ + rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp + gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B + /chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ + /cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ + A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy + get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} + ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp + fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 + {2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add + chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ + 1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} + forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn + /BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put + }if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ + bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A + mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ + SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ + userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X + 1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 + index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N + /p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ + /Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) + (LaserWriter 16/600)]{A length product length le{A length product exch 0 + exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse + end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask + grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} + imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round + exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto + fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p + delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} + B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ + p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S + rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + + %%EndProcSet + %%BeginProcSet: 8r.enc + % @@psencodingfile@{ + % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", + % version = "0.6", + % date = "1 July 1998", + % filename = "8r.enc", + % email = "tex-fonts@@tug.org", + % docstring = "Encoding for TrueType or Type 1 fonts + % to be used with TeX." + % @} + % + % Idea is to have all the characters normally included in Type 1 fonts + % available for typesetting. This is effectively the characters in Adobe + % Standard Encoding + ISO Latin 1 + extra characters from Lucida. + % + % Character code assignments were made as follows: + % + % (1) the Windows ANSI characters are almost all in their Windows ANSI + % positions, because some Windows users cannot easily reencode the + % fonts, and it makes no difference on other systems. The only Windows + % ANSI characters not available are those that make no sense for + % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen + % (173). quotesingle and grave are moved just because it's such an + % irritation not having them in TeX positions. + % + % (2) Remaining characters are assigned arbitrarily to the lower part + % of the range, avoiding 0, 10 and 13 in case we meet dumb software. + % + % (3) Y&Y Lucida Bright includes some extra text characters; in the + % hopes that other PostScript fonts, perhaps created for public + % consumption, will include them, they are included starting at 0x12. + % + % (4) Remaining positions left undefined are for use in (hopefully) + % upward-compatible revisions, if someday more characters are generally + % available. + % + % (5) hyphen appears twice for compatibility with both + % ASCII and Windows. + % + /TeXBase1Encoding [ + % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef + /breve /minus /.notdef + % These are the only two remaining unencoded characters, so may as + % well include them. + /Zcaron /zcaron + % 0x10 + /caron /dotlessi + % (unusual TeX characters available in, e.g., Lucida Bright) + /dotlessj /ff /ffi /ffl + /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef + % very contentious; it's so painful not having quoteleft and quoteright + % at 96 and 145 that we move the things normally found there to here. + /grave /quotesingle + % 0x20 (ASCII begins) + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash + % 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question + % 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O + % 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore + % 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o + % 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde + /.notdef % rubout; ASCII ends + % 0x80 + /.notdef /.notdef /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /.notdef /.notdef /.notdef + % 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /.notdef /.notdef /Ydieresis + % 0xA0 + /.notdef % nobreakspace + /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot + /hyphen % Y&Y (also at 45); Windows' softhyphen + /registered + /macron + % 0xD0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown + % 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis + % 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls + % 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis + % 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis + ] def + + %%EndProcSet + %%BeginProcSet: texps.pro + %! + TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 + index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll + exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics + exch def dict begin Encoding{exch dup type/integertype ne{pop pop 1 sub + dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} + ifelse}forall Metrics/Metrics currentdict end def[2 index currentdict + end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{ + dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 + roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def + dup[exch{dup CharStrings exch known not{pop/.notdef/Encoding true def} + if}forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def} + def end + + %%EndProcSet + %%BeginProcSet: special.pro + %! + TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N + /vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N + /rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N + /@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{ + /hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho + X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B + /@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{ + /urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known + {userdict/md get type/dicttype eq{userdict begin md length 10 add md + maxlength ge{/md md dup length 20 add dict copy def}if end md begin + /letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S + atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{ + itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll + transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll + curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf + pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack} + if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 + -1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 + get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip + yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub + neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{ + noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop + 90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get + neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr + 1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr + 2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 + -1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S + TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{ + Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale + }if 0 setgray}N/psfts{S 65781.76 div N}N/startTexFig{/psf$SavedState + save N userdict maxlength dict begin/magscale true def normalscale + currentpoint TR/psf$ury psfts/psf$urx psfts/psf$lly psfts/psf$llx psfts + /psf$y psfts/psf$x psfts currentpoint/psf$cy X/psf$cx X/psf$sx psf$x + psf$urx psf$llx sub div N/psf$sy psf$y psf$ury psf$lly sub div N psf$sx + psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub + TR/showpage{}N/erasepage{}N/setpagedevice{pop}N/copypage{}N/p 3 def + @MacSetUp}N/doclip{psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll + newpath 4 copy 4 2 roll moveto 6 -1 roll S lineto S lineto S lineto + closepath clip newpath moveto}N/endTexFig{end psf$SavedState restore}N + /@beginspecial{SDict begin/SpecialSave save N gsave normalscale + currentpoint TR @SpecialDefaults count/ocount X/dcount countdictstack N} + N/@setspecial{CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs + neg 0 rlineto closepath clip}if ho vo TR hsc vsc scale ang rotate + rwiSeen{rwi urx llx sub div rhiSeen{rhi ury lly sub div}{dup}ifelse + scale llx neg lly neg TR}{rhiSeen{rhi ury lly sub div dup scale llx neg + lly neg TR}if}ifelse CLIP 2 eq{newpath llx lly moveto urx lly lineto urx + ury lineto llx ury lineto closepath clip}if/showpage{}N/erasepage{}N + /setpagedevice{pop}N/copypage{}N newpath}N/@endspecial{count ocount sub{ + pop}repeat countdictstack dcount sub{end}repeat grestore SpecialSave + restore end}N/@defspecial{SDict begin}N/@fedspecial{end}B/li{lineto}B + /rl{rlineto}B/rc{rcurveto}B/np{/SaveX currentpoint/SaveY X N 1 + setlinecap newpath}N/st{stroke SaveX SaveY moveto}N/fil{fill SaveX SaveY + moveto}N/ellipse{/endangle X/startangle X/yrad X/xrad X/savematrix + matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc + savematrix setmatrix}N end + + %%EndProcSet + %%BeginFont: CMTI8 + %!PS-AdobeFont-1.1: CMTI8 1.0 + %%CreationDate: 1991 Aug 18 21:07:42 + % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. + 11 dict begin + /FontInfo 7 dict dup begin + /version (1.0) readonly def + /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def + /FullName (CMTI8) readonly def + /FamilyName (Computer Modern) readonly def + /Weight (Medium) readonly def + /ItalicAngle -14.04 def + /isFixedPitch false def + end readonly def + /FontName /CMTI8 def + /PaintType 0 def + /FontType 1 def + /FontMatrix [0.001 0 0 0.001 0 0] readonly def + /Encoding 256 array + 0 1 255 {1 index exch /.notdef put} for + dup 39 /quoteright put + dup 40 /parenleft put + dup 41 /parenright put + dup 44 /comma put + dup 46 /period put + dup 47 /slash put + dup 48 /zero put + dup 49 /one put + dup 50 /two put + dup 51 /three put + dup 52 /four put + dup 56 /eight put + dup 65 /A put + dup 67 /C put + dup 68 /D put + dup 69 /E put + dup 70 /F put + dup 71 /G put + dup 73 /I put + dup 74 /J put + dup 76 /L put + dup 77 /M put + dup 78 /N put + dup 79 /O put + dup 80 /P put + dup 83 /S put + dup 84 /T put + dup 87 /W put + dup 97 /a put + dup 98 /b put + dup 99 /c put + dup 100 /d put + dup 101 /e put + dup 102 /f put + dup 103 /g put + dup 104 /h put + dup 105 /i put + dup 107 /k put + dup 108 /l put + dup 109 /m put + dup 110 /n put + dup 111 /o put + dup 112 /p put + dup 114 /r put + dup 115 /s put + dup 116 /t put + dup 117 /u put + dup 120 /x put + dup 121 /y put + dup 122 /z put + readonly def + /FontBBox{-35 -250 1190 750}readonly def + /UniqueID 5000826 def + currentdict end + currentfile eexec + D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE + 3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B + 532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 + B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B + 986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE + D919C2DDD26BDC0D99398B9F4D03D6A8F05B47AF95EF28A9C561DBDC98C47CF5 + 525003F3DAD7933EB57E7DB1462E9D906F6D8F5BF740206C1EC5F36E00AAFF68 + F3EF6F3A2540E5F9564D1C215BC1E7E69C7D04DA5DB1CF195613C9CBF4BAA360 + 84AEF3E10E24877FBE36AD731DC97305BDE6DB1F934909FAF60B8E28561FBC57 + 0F5B6225425BFDE8F0C71CD4507B82FF803E9A301397975E38A259DE1E1B4FC0 + 06BB1DC2D45B987A2268A77CE8DC025CB0D1B39788BBEE149103950650171C94 + 5FED1063050A90BD38605BD9365D1C2AE42A7DA3DDB9A263FE10BD487F63D908 + D4F02758BD9D7BE53E6353A25BEFA29E42B50C1D078A8B3A746EEDB381CCE36C + 93FC4BD1A8D1D6ACD0D355E948CFE397B74D243EB51597D251D0BAE6884D70E8 + FEE119462E1939A9783414DF59EEA5FF1529F13869D1FF0A44935C5198CC5DAA + E1FD2A17AEEBF4974052D06734A409E26C457C06700C55896C90BB33E044A737 + 46590D9FA242819B9527FD59818D8829D4EB2D26A34CC05A2CC063E66F2DF193 + 8E4F9670014BC243180E45B51DDB05AD1E6A7F619EE1CE09CFC1A4F02CB7270E + 4482FEDF673EDED38EF3173C475C34BFB3F6623C5E942A7797FEDDD0EF1D54E9 + 1D90D7076C0A9687E334907C22F2E7C603388D8D626B0E5A62B7543DCBB575D7 + 9A6BE1528EC9BC18570001092524E4FBB02F3B29293BCB4F0EF14A2DD9DB22A5 + BB33455799E8120D2A4862424AA4A382972E2845E042506FC8F6E201D11DD0F2 + 09FAD8DC29C3E12B66293ACBFB13FA0F26238981F2CD52B47A8CDE6DF5CDFAAF + 3113E1A6366B806EABA9C34E5D41167CD10D7B639021FB4CFDAE28CE72A93F3C + E8929A4FF944457C1E9A87F12424001E65E9F582638BB505B23B05DA244BA609 + B7FD15A3F53E9A29BFE83BF5E2418DBD97909464792A1384C8D56E8B7369E43C + 436FDB9D76C84D3BC741F8EE859011AD981DF87DA30A9ABFE05CFB1C1AF3744E + 81F397FF172340AE18C47CFC701ADC9BF42059ED5913DBA9321ABDDEF9A1B2C5 + FEE1F83DE6E65085117603B9E9366E0BEFDC5DE1ACCAF6A8731F47B547CF08D7 + E61C3117969E6A6D58E9AE4D95855ABD3B320C0C1B77C65F0515655C924E017F + 336155F783C88D6F24F708E95245F5D1CEDF6B61ECF7F3E0669700911C1D9238 + 45BC7F6D5B5FE2562D27ECC8CE9F2357C2A98C3081A136330A44DFB68CB22BA6 + 397920A9158D51A7CBEDEBE75E9B065629D9B73C16008B8C09C04115E84FCCC8 + BCC50070387308B1BC640EFFD4AA2C6B9965D9C28A4549E78E55FA68D5A0529B + 95FDB74EFA81E618C7ED1CDCE8A3F3EF2990A8875B237A72295EFBB3CA808F4F + CD27738B26FFDC47EB8B8844FF1CD381DE6D7AE7FD40BD5C7C57A0CD3E7DC3DA + C22F764B65DE8194EDA661B5520F97D1393377E54ED30DFBE9B8090BDFE5F552 + EA14220F883C27C6AA4491FC0499C5FBAFFE659CDB1135B08BCF1F0290849EF1 + E179BC8A900FC0D4300204671841EB42A8A4B3AC3B8A2ACDBB53B27CBF172B36 + AE15D59174181D443FEC5AE5F0D3EB62DA08ECC0346526D8898B75C78C7DD9BC + 7ECA10FA14414A20FD880ABDF3D74B4F51B410DAB44F9FE66A0B9B007617CEF1 + FF65A8DC7F4313239B6AD5E374D4A01759BBA5109D4CD57D0D2EC09BA8AF8FDB + A1324574BE9B2DC1B5F070CFD75A257BA08E87A2D475EE248FB6F9DB0181FBDB + B90E92792A2EF3D7CFAC468D446A0F4088FBC80D72CD0BFA56A652903942474E + DB4030F4CAB2E1429C21B8790D1B7141F2E9D13C94CCF2648545C302C70FD880 + 8B8BC34F942F6D0E959655D57E91A77A825581D671994BE7969D18FA3CA00B95 + 5E1A631E96EB63D14386603DD8AAC11F0E5ADDD1748E96B92699A58508838FB2 + B419B66BA294CFE3DC6A6B40E25EB130EDDD33ED3F51D1BA8A2E926FCE901419 + 35308842AB4DE799CD6E607FE59D8593AA8B87E0EFF0E0D499D8291F4F316B7B + 47A2CDB0778045117D85F0F84D74E667C1A9E04F26A3775A714A53EDC7C3E319 + B66FA103D9E9CE115E132F5C55181E8CE5181AE86D8B7D5C0C7C949AE04A0092 + EE0600C018E652ACDB9E61C845533E571C77862AB44EC1EC56DA22E3061D00AB + 9860EA0B3A1B75A6646058DA37332AE54694DFC3B1AC749940E5E4AB26B61A01 + F7A07E21DA83DB920BF427D499140F14CE97FC85A38CC2076C544DA92FD3B0F4 + A0D15CCB6F1E7CA5C6FCFDACC4BFE1646B36925DE625D41D2B3B65ED398406D0 + 6392A579D04F2F3FF6186D4EEC55078C9E94822328798725B9302A2033DB644D + F40D22EFA88ADB4411C25E815DE5F4B85564A89C7F41B7E714A3C1E35F4A4DEF + A2041DF4FADA179AB72378D070671AA994D8BA2338E75B9319CBF9DCA6861718 + 13DA205038A72B55D0B22CADD4B0D51D35FB9F98773B35AA5072C3943B5FD2F0 + 2F31DFCD42EFFC5151439966F8FA3B855D73DE5DDE960E8C888CA936230E6D3E + D400991C1FA00E1EB45193563E9EAA86604859E0C77056A0C20672AB461F82F3 + 69680CAEF7E9BDE4ECAFE968C07E1A4A5EE1FC048057C01A36E4EC90A9593963 + B87377C2A195B5BC18DBE1DB2EE413C43E19031DFC9581E5D797A6FE57873D3F + 43FEA7029A20DFED357979363EEF044BAFBD767C4B2CB5A6F8AD4822DF42941E + DF9D07A3B6FC661ED642C59F0ACD949ED72902C4C1EE5A85AECE2875D3061597 + 599D52C83445EB1C5DC6771FB7DAA604882BDE15F3F76030D9938C8433B22814 + 035C6DDAAD15C401F16E07EBF612DBD743E7FE9E2302107EB6F7605BB59DC91F + 62D0657206FC9091DCEDC8303C414E069639135933BC8766A4B69BF20BC83D34 + 20CD2C51DF90754578F7CF2425447E6B1A65860EBFEC2B750B59CB3F7E0CA71E + E2D9711F4E4AFD0549965C368DE5529CE6777E0C17BB4736C09B8DCFB42DF4C2 + 8A4C75E02CE2E646B830887998D41F89C936F93FD0B5915258602017F4D6A3B3 + C5ED9BE3D18BBCF2CA35024E0C8C9F2000638DD04C8D210DAC3D0C0BE032A694 + C37726DA0888665E3CB379275213648E7A37A92A1916540A03F10D30C95937FD + 87EDE4C3E4AFAEAC46E39146D2D775FCDC4B17676FECFD1593A0ABDFCBF3A943 + 5ABFBAC776CAF22EF77807E9994434060D3E27DDD6CF0D180035F73B19265B62 + D6E0CAADB100DB6EE62DAC0B7AA72BF9D6B84DEA050F6242BFA7CA42F8CEAE60 + 32E89377D62E46144375B3B0365C6F7D99F679F00F91F552F826EC6F79A674E0 + A0F87E87E5BB7F8593C9B1A2002032615206A186822E174737D14D14855E45B2 + 4336E92DB9796A3E1146FA39CA3A81062F9B9D996DD11D39D430221BC695B764 + 5565118B52767C74246B80E913777F51557933738A78AAE6C864520F5F02A75A + C0582A477327D9F7AC2EC9A4625BBC1E80DC49565D434775E9A848D3479186AF + BB178C13FF3D8C2DF86233A6CE9A1C43A4AE82967AEFE3551AA7736574DEF17E + 42490C1B2EA953399C22B428E4283DDF4061FE92860F42F2E708B099E1AC7B1F + B183562C7C91ADDE1227596A7B22571B160FD78D489248AF9765CC6827FA2558 + 98BEB5727B0B2F58CBC0011C60EA0C9824827A1581D596299DB9387B9FDFDABC + 9D4FDA7997575E4ABFD62CCB7F7371705CAE487645E9A5443A43F68D2B224771 + 4611C09006173DF3458098C769C77903F142BE5D78CCB4AB33A980CEE81917FE + D4C4EEE3ECD0F5D5B67322591AAE7765EA2E088D25405AB6B84164D57C86F76A + 4B121532941C44C544F9EF7A02DCDA42EFDAA8F98A3AE49E5EC978C1A68EB766 + 66D6C05EAC7A46C45BC24E3768AC221A49F441EA7BB3852CF8A2231802FA8109 + 10B90F87F126D384B01384DCDF0A6FD6F2D909C04D88262EACF50E0EF9648F22 + DE1973B0383EEC8C1B04087F459903FC1EF8E74C6ADA64AB0FC66182A4F540F2 + D200511854B680655EF011FD95D7EE015FBB5C109F140F56935F50E74F1ED6D7 + AA7E698510F3F42DFEF62C8913938EC6C4262809AA555DCD8713B5C502E82534 + E46C0154B8F7BFE7FD41AAAF3BD73640842A8CFD30C45ACF27CA03DA64E57D10 + C91F58C3DE6BE19EF868B2659261664FE190F5CA6144E77ACAFC40F56608F38F + A51C115BEC032AFC141DBADDD5E7E8B0B06157979D336D0D4DA7D4777FB84710 + 95B614BB1633DB62754C009661E111A0E0B55CC91260CE24C915119FAE19EA89 + 4E58163ABCA0EFDE7855EA96BBB2627F5444ACE33284758CB5E4604DC6B26F65 + C554D7513C4C47500FE187B5220DB4329C14E35BA77D67B6D51A53CC33CABAE5 + 176178C5B70F3CF453F2370C168BCD9681D8F87F4A7E84BEA7E6F206166A93C4 + F618E43BE8D8AB29B802C0B372180BD0AAD2BF87401B4021CD361472A448357D + FC82D30891523B8B19A8100FC0711BB8EB19297C92CC27A3B395D98C922BB390 + 62211282BFB1AB8DD10D8E5DC8D43C77B058C5DA197178462A6EDE6B0C834BA0 + 09A24792E4562CA672F5E7A0560E948D4727F3AE1194661DFFAD58AC14AADA62 + C8C0DC04C47DCFDEE0E68E733CBE87CB4764D8CEA2ABDEA98397DD9C3D71C3AE + 54CBE5642C9C8126654452D6242650B6793EE45C9686B0ABEA44B8FD7380B171 + F7EDA46A0E5ED45313B15C80A27C446AAD18D85637899EFE29F501349DA7184D + 23B5C48A909BC90B34F3494C9FAE5C1A8D6E3F2BD60F5AC41073BC20E7E4B57D + E914BC85279969D6C32ADD5EF443ED195399F3B292A146CA5DC57A0BE45E979D + F90279E50C2C8D381D1869F2C5FF511E59008E1BB578430EFF98279249D20AA6 + A7976D3B8BFC8A19CD1262B73D3DDB4E6593B9F390D98F27F3634D2A54B81AD0 + 00EBCD250D37C86605B717AFCD48E4F24D22265F536A096FD9C1D300DA1AAD02 + 660E6C282CA3DCB58C39F89761FDE2686A3008D155128363876E38083B4A0489 + 4E27EDA8C4516972BC3AA50029BC785CC384113734D378E19A626FF9B30D21D2 + F8E12D85067C4B4774E98923158682DC7B742E3B9A09E28FBE4BA3ADC0DBEA47 + 27CE94B5A5358E625B1F01DE33B7D4AE4E128829DB8F1129F20FE88DBFCB7FE8 + C536191AF1313DC245B8DC648DE288B76BAEABB664791DE59CF5E63F7D493374 + 89931636FE5548E5CC900FFAFC0D98E2DB3157503D94A4A2BB006C41B90FA53A + 5A69954014C00A025C06CDB05D800A873D030A592D60B515EBDF675714A62432 + 0E33AE6E2F0CABE30EA7397B9DB6D4C476345567F61ADB1FD7F355C3B3997975 + 09A25DE0392D2A83147159416BAEA08D7F49807C5BFFA3E5EB02C6501381778A + F9D26AFA8E72F40A9612C2E3B442F895345C9364AF375A5EFF3032BE0D11B440 + 3D301DCE6464E24F38F3F75D2089CCD1EDADC85726B116AD13499E67BD64B122 + 93EFD8FD2E481B51BFC14D6C906BB1B433F402E5340F964E45C82F84939C4FA6 + EF46BF638C7C181AC7CA38BA43F43A59A970B3844A784BFCE612656027D015E3 + FE52A870F8003DE0B3D957D610669E7A16B231C89889AEED9CAEF026EC83511E + 4D366A2FB7B27BAAB08E891725DBD2FE629EF71D1D2E4EAE0F6BAB6B4F9F4B36 + 86D515B398C18DA12F0C968D102304EC69215F3C8520751A82F9B6F0DA26886C + 58AD3DFE002008308E0B0A5E2221DAB4E5926E384844C24E6443ABF6923C6D8A + 94B13691241C5645FE1A58AB580CC3BDC5EFE27639002D55C7CAEC172E87C08E + 88301F066E05DFF8A2FCD8919CDDCC9A77D7A27C690AFF6502AEEE8A6F0EB510 + D6B12DFBCF6B599E3D68F6C8C4177710C85DC18AB5FF7B659020212C8E5FFD14 + ECF70C24D59E5C25D1995B87D5B422163B0AAB9E059615F9EB2B2A805AC370E4 + 5E09B27D7C8F55207084D59D1EF49DE1910D90000A4AB99617BB1FB7FD5A16B9 + 9BFEC4510E4A7A08329624F437A48F2131CFE7E52C71EC60391F440978342DA2 + 9AC01EA8935BB444436008109F423268CCF8BC468E5FA7718B0E46F2DFD81EC7 + B7CA83C939F95B7497EC8A7DF0829113E720876FDD94E07665F39986695436C4 + 43CD509D2B4FF3B78F7D6758F3D193E341CA8E617697EE47065D641AE93C5519 + 589EA8FD039EA66ABC91837713795F93D0C1A5091A95746FAA1B6E70C2CF8F53 + C5752934EF9401A74FA39A3CBCA3A97ECECBCFFFE3923A7421220EF5741EBA53 + 11F684CA2772AEB595168342AF0D638F0EF8D81E9AD907662C2D7BAD0C042DF1 + 637D15E434E76B75601864A1E2C92CD93728C23F5B50810B5CA32BA7BD876D56 + A0C21A24FBB7E34C92CB1789E1CE4C01F67783B8B1A6EAE9B0902CAAC2ED640C + EC932453CAF592A51C61D544915206C32364273C7069FAAB8AD4CD88DBD2F4CC + BC63975566BB70093812F7703073DC63DE9967A0E2BE1636E9A5B96075D6B123 + 3ACEC1ECEED33DE7C6C2691AC86C9CE1829F2139F0A7CF84F36DE89CF2B26DDB + 324C94F2216C14CB0311E11FC05DF1A3AD68A68E28018BD89C4552BF58D94873 + 03AE682F197D8BAC2215FA66EB1FDC278E0959D39F0A0A0DD709707CCA242FC5 + D20C275C9FB45EB7C4FC1DEB512E5ED74C279C76367279782B766069A5D40541 + EA3727EDB0BF53FD330262C5A111CA7F832482128C2E86148D222C4505ECF019 + 86303D389742CEF7567626E830EAE21726E4530763E213D090BA52417238D196 + E9CB44786A22539FE00E7520EA799BFA232ABF75F987C5A3111BFFAB59812217 + EEB48AC9C4E796FD75E34AF650F604A7221378FE601E8EBF6F773911CE0E181F + 4444756B9D4B6734F246B9BB22243A6D2D9C107B010D9BF7B7C875CF77C45F32 + F0F117898EF6B5C5772BC24621E9611F449CE3FB3531217AAB661F818DDD5818 + B27E9A829DD2E02F58AC20094F0B03F9EAE12741370BF0615BCB7BB6A4A31774 + EE3BC414B8353169193F04EA19A369622CAC88B12F96F49F32832A3DB0625803 + 0CAE5B549A19686C12144AF2F61D56FEB9E309C22079E588729A798B71E7E4AB + 8D120F496077B5502EEB9671E1A03F686B465432CD826B93F352306AB7B6E6FE + 5B96FF9B99056E8CFB0A0CB531C6C8AC03F389D16A8A8227367A4EDA16A58E08 + CD832377CA9F357DCAD04B89DC92EC206EB02EC2D447A7CB0EBED3565F32AE09 + 95440862C4FD12896A3D20FE75FDB856E73D6DECBE760AC588FE15BB6EE22150 + 02D52E17376F98FFDC89C2E65BEFBC5C66A808BD94C66359E9B1425CC4A87D6D + 15139E8A2CE29E56C616F0B2EA0334A8CF195E9228962F4E54E189C1762FCFA5 + E9CA25D4E5D92B047D3417880CA901DA337500F7C2E33331E646162CABD84720 + D0188B4901763AE039A1C900F84E848E872C3F19717B5B89462A40ADEE83AFA6 + 83ED2DE12815AB7440C53E3B67C66D4037E50E23B7C7E4CD63E60783F538D02E + E8908F859496511AF190EC1EE32475A660E5F73C2D818D86EEAA33AEDDB38374 + 94CB37935FA5F7FF0D5E8FB1AA7293614988779FC8D3DBBF71B91D15BB19CAEF + 5839525EF2B70604B84B8BE674A5F6725A0BCEE85B9CC23E875EB08A291F6A28 + 0F86ED2E23EC07EF532EACC1EBBEA8D8D9813C8847A1F43FAB7FBFDCB6019803 + B0DFB5E77620913DA0843A8A9DD07D58A2D33383028CD0A3BDE4D9F5E8E77BBC + 110FF66CA1A46C3CAA035935DB6B4DA5D402C941758CD69DA3287868DE48072F + 690F53CC6EA311572F300A19E7AEB562F71130F5E933DB63AE4DE2FC18445786 + 49457205106E73CBF9872CDF2A33854298B686C53D214366BACE26A52455549F + 4A2049DA836F9C7738C61463D65929E2D2D5D18D7AE320776F2AB9957CFC68FD + D34BA755F01DF7E875F0D914A253F6D79A7A752FDD54EEFBBC901566ED996D9B + 96A102A85311DA55167632C052273BE2ACC9AD8247F584EFBBFE0E0F8ADAE707 + F806A43D0F13CCA1D49BD5890408CA2982F165758B57F97ECFFE98967167BB53 + B2D54FD70D1A230B54C7CD9445F8A3B219D87795013FE8D5027CB7FD4A7483F8 + 73B5B95AEF96670D448DE74971B2002FB0597F5DAA0781183DF734486A53E995 + 079C7B0E0C5A527DCCEBBCE145E7F29AE385E98C4F9F649ED31BCFD1D2996235 + B46DAEC5B3B02FDEFCC298F1946CAAADCB2EBC5EC2F682CA702C59C13CC04AB4 + 7F141CD78AD64262FB36D5BFB0B85DD410EB9BFCA65D4C2DD256C01E119E7C74 + 2301E949EF1F7AB1D8853565A268175AA8755F6CCAD8F2CD309F3140889A8972 + 2210C58E020CABC064A83547FA88F6294F4AD3DCD26326000AE2B71A32A9DD88 + 9065875144FC87921BD16520A033B5295539269ACFBF00B3A231552AE21CAE0A + F628C03F7D231F8BD250318351A856688A75191FB843642AE55ABD0593641BA9 + 5C0B8A3D9709EEA4D643BF29625A7C5858DED2DCB516AB20BE940E9FB4F61793 + 4F97347D2C7FE13227CAB7E7FDDCA0CCEE3E0E4069FC9576566BAC22E8ADB935 + 788230B84EC7C4442037AC8F4584C660B94BE1D6CB3E160D3D5A4B9029B40D01 + 24A3E1553A22A9E1D263338BD212FF63D9BCFB3DF18B27B6AC3C19AB3FEB3795 + B8770A63CFE79C1CEDE1D257409FB133A14CC354DD0363B673E6E38B028D1B78 + 925AAC8C1944A9C92416238D29E0EFF9688256713000D9FD8413235729C160A6 + 0F9268B8C560A7B7A9C166C8604168063509B6292C788E879C6F8707CF1A6E39 + D7C52449DE518A87EB40C5A9F9D38DE9173395A5BA12F23B9FD66D4AD799C0E3 + E033C70A470BCAD1CD85BDA04B23CF10D8BCFFFD1FE0530985FCE38F0BC337A6 + 9A29839F309E55756912B60DE680AE61BB4AB797A6C8BFC8DE00529A36BE9B26 + 238F8504B0D05CC5E38D8F08F1CE26D36B75E5D9D433512A6075BF92BBD92120 + E85BD480F913880B269867E1BE12D963172DD4AC6BA0338B0C820A6AD8D9B656 + 084DDC4CBACAC5794E5789BD1AC182DA6735B42391D7F03C1BC8A62723D33ADB + 3544013348C24B737133A2808B972338B59417BA73EDA3272FF56C888B3910B8 + 3C7F0DF26F0652BC18359B0927F17CBFC0CB151AAE21375E4145547C2091A241 + 5F4C79583216BD01CEF34F42080999002A39981C381CD4FEEEB7D5FF83D01758 + B3418BC83A29BD3A0D32A2840A8B7264B7DE5D8019ECDDE18ED5B0F6C6DC5A5A + A64380DE281957E4D00B57E789B9C484F049AA93E3D62289661562CCD3C1532E + E83EBDB19F1F1651E6D09C640471331C9BC30CB0F309BFCC4DB339A3FD22CE37 + EC0DE400566583C760CC2E42E18EF3BA45F3CEDBFBA56282630A411ECB6DB65D + 5F94CEA00333F471B5CE7187BAB0F1E19AE44D400BA8D67683160FD68BF1E2F2 + A0B0D4742A0E1791B2B8215C3481318263D72445C1C46FDCCBE2A394D534D482 + 6D4431D0EA26DFD0C385E904F7DE8E1152081C2DEBFDDAAB7016641E8246455A + 338203C9863ADBDC584D536A43259E79B27A5043C1B248813E6009751D0EF91E + 5F82B0833D512BD31E45967F344338EE05E0EF51579A1B6764039C77533F926A + 1FCEF61CF237F5ACA5BF26C8147EF61CAB0007B071A64F1F9191BA374CC8F1B7 + BCB93343D0BE342588E0F098A989349E618D4CD5BED5FBFA301B2EDD077900E3 + 04C919D5B6F92CE997325C2E72A415FE1D16B69BEE620CDE17254DDC510FDCCE + DA9A4EC064E386683C8C46C8CAC7DD8DE608335F9AD79999626C9014A23FFE9D + 77753BF8DF52D5E13BC374F853BE7122436F184D502F6D7E2686231AB76BE849 + EC2AEB308461EFA0B60D342757C9B401B645ADAD98724B5A90EC684C259A440F + CFDD2D725EE0721B843682A5D21BEBA4F4F7F613BB026942C6C67BC28C2BAF8D + 86A1B771996787888713524E2EB29A09B8F9A88EBD53D31D5123E8DB0D008939 + 1E175E8E021E605464782D5FE01389DDB09CD3C3ECCB7B8AE26367D28E2045EB + 44924D111B714BFB4A70B052AA7DDA532DA240F13FA13A2DB889188071B4CDDF + 71FA3544C581B24DBF7B8D533E8ECC92570AEE7FC0B9485E21199097E3A20BA6 + 7420659364A624117A2EFD12761169D98F426733F1EE7786D50B14726EE395AF + C62C5C34523EC441CA2E9C00D585DEAA0230E2BB74090ACBE659C617A854F827 + 26A867A40BE3623F57474D2126A53FBDC208BBDA1BB34D2C42579EF5FF9E0D0D + 5591C5C56E37EDA90B5B569CB4670969523AB26C6C01B24E1766E066ED371C0B + 4330AFACDEF310D05CFB9839AE022C6B11E01CD0406F59894DEC5212228208B8 + 6869B5BF4DE40AD2FC90FC9248284191B6C58CD3E4CC379C9D0C72B16E4009CE + 1439734B74B1B850F3C62D7DF80F84C6786673F948ED5370875B6D7CCE0CB9C8 + B5D6B9B52F5864798C4D549CDE2EAFAE6DC6561231305EC10B7EDF036A0B7376 + EB5F5E1918D85B8D473BC971C64E53ADE7F1C6F6B5725029AD4A61FF9F41106E + B3BA9B9EDCA368D5262A2EFA64AE3C02A95B89E344F4C5695EC935EFDB6A82E2 + 1F7D558AB7790F65397DC347890ACEC7C398D9B58EC1B546A269884708DD9869 + D30D0FCFC6F07CFC26CC0D0020CFAD6CFB71D6A12318025E7B7B4D3343944EA4 + 29FECACDAFF65AF32EE2BDC260DDB07B796FB9A428C67112A1128AD751158428 + BFD7E231E513635D07F39238E14CD6FB9E8215BB2BF94991D56DFB0619FEBED9 + 5BB3857503BFE30EE27FB33FC278542E02D9444E1448A1CBC1B293DCF7D067A0 + 62A3DEA1DADAA33D6A886C258324EED976B363ACE3017EEB1BF3BCC2650AEE5D + CE9BF882A1A0E8EAA367B11D59B20BE5D66B137DDF5A512EB369D72D81ABFE98 + 83C3B49FA3308E40FB47B037041E97F96BE7433665D1D73F17DF6BF2271AE421 + EC2C297BBCC2FFB6ECE4E46BCC1ADD751BAB46F482368BB3A4E2CFD907307C23 + DD6743C9C48904C4C621373FC68F2A4FA949D80D85F0D0069D5CFCCEFD50E626 + 5DF2C5E1FCC38F9182FCA8EB4541A66A2C57D945215D154A409F2C1D12F3B79E + EF196D1F538073074280CED6C931F941B2DE625CCB3574ECABD1959BB996F262 + D7443B23D9FA814B01B5F64489A0257035A7FF5C68A5AD56868A1BADDF29BE6E + 046B7D8835C8884F36F8D04AF8BE351ADE8552B0DE6CF672BBC75FC8EC0BA66F + 2502DE85BDAA9F47296A60919988859EEFCC5FB9D8698D5321FE517C16C4B3EF + 88328A2BD5850F4BE6DAB38F3906B17E5B70FFCE2439FE569783A34680D65CF8 + D185081E33953FE6D96E368A0275C3E63620CC989747F7420AA98E6B14224ED6 + 88E26870F5E0D4EB55CB2AB8936CBB665D3F6FB8D3E57A2A981BF437584E2379 + BD6F35564B488C7610D709C2F77743840EC3CB2A03EE9D23E7AC051B92E4A6B2 + E1569C734B6C8AFC4EE8A14BBA0543DE13B76D081FB6C8A3297DFC1149CEC39C + DC6437729DB3EF60C0050C2A7AB1A4A732508F6082B81063B45109C4A8A5E2F4 + B50A57A324B824F64CD69FF37C3856801DA0512796C4098FCB1AB5EC2577D73E + 0036AAEE4354658C27C4F34DD42406EA3142DF61EB4500EA7F4913DD5A33D4D0 + B08C78A43B268F4D8CAE440FEFA5D9C43ABCBC37EB3EE81175530B60B6A7BA45 + C28F48717B0831F0A9E4E1F1B4534603D9C1FF06376FDA2434F3F51E59EFF6B6 + 949F432A4C8FCBC2E42D94D39942670918DB0F5E30E1F0C43963AFBC1E1805A5 + 58662CEDC8C6AE336F7BF10946DBA47895FB594DAB2F702599018264B172064E + D9DB51C57900BB3F2BB613D535A1A0E90D72B47ECBB20EF15E41BCDD69B4F6A0 + DBD23620F2EFA746CFD4E2E0586B191D35FFD1BE741DA9716D8DF76BE3CDB250 + D422AD931CE503A5711667D4102EEECDFAC0BBB27CBEE80D571BA4CF55D4EECA + CD656FE51C05333B6A54C20557A8ADAE0E560C7F6855C20355628BE564897C7A + 805928087603FBC672023A57F3AAC5E5433D428D6587380E61D7AE0C392F0422 + 4E371790601867A0828421D308BD33E1912F7BCEC6F9676EC366A1A83AE73E6C + 1398CF331A8D4FCFA411C912365DF375FE34F2160A86626C14F210B6C23F325E + B32EC144604B2F95ABE78378367BBF15BC8348309A33BFA645443ED8CB924438 + BBC5A78C7ACF0EE8852AF36510C51E0A159D545699764FE7DC7F18B0BEBCEC1E + 7E3541F0E5E5D3D566D962B55DF8F024239C1E25560A4511507A78BA7A60A242 + D9A20085A6C1ABFD63AA74F77A7938A525D97BAAB29B70C08374E35AE18631AA + 2737C3B9D120716BC6689FEE0D788EF588610311567955BF5B9A8A7BA6512B81 + 992A1ED3CD580ED21620F5AE680D78953FCF188E950333E3DFE43002E5B8DF1F + BBD866CBDBC54BC5160E53EE38171F56728F24A350AA7843F8D0784526F15A4B + 70319BA3A303CEE0DC195EFCA8D87B52551C14484B741352530D639A28627F8B + C0DC2EB5B51BF3EE8C66E124B4F9157D2223E0C64D030C9CBA2B54C82E1E1DE6 + D5C5CB8EA61DF2B704B76F6527E88EEB3C0AE9A876745B7309561F6A738D13DA + 3C1566C0E5BFD3C45740B85EBC2CA5ADA4D6CF75C4364505C451AE2F04299A64 + CFEE478708472B69CB1AB52C3B24B1EC482B4434F20CB7BFBEE0F8E833497646 + F307BD5CBBB15CF32B0A5CA2C38F80C56AEDEC2BF5D4169695519AC14ADE4C80 + 1249AC467F47FCA3A9A37A0C66779D7DA271A6D7F4BDC8794E9278BD1B076764 + 8CBD9DE70477B70D34E0CA6265165A609CE91CCB7409DECA531D459B078EC038 + F5401CD25F7A3B12F67CC3A6936FE1B9DF4C38E7745F7B5E6F9E8A539435CEA4 + 311DA0ED2DEA1C6BCEBA6F05F88847A7CB0C20CBC3F7B16EBAEDA01CE6C13864 + 290A26230DB8C78B4DDFB67836E856EDAA76CDEE3A7A1DDB42228D5D9358DE67 + 480DCD381AF60A775E5874E88A0DAC17B4B5A36BA7125CEC348672D06AE5E21E + 60518BD5C5CA5EC09EE111D93D186E21865FE6E3D9695098A899AC5A8063D4FC + C82FC6FF54B7480D61B172A29225FE46AEEFB24057C274AFFBCCAEF3CF8C2AEE + E78BA31EA7260D988638E6E11B4189FB731D40CC74F2248E07382582B0962348 + EBF21432733766BFD5778CC0F1D2D78DCA3653D69B64CD81FA7E2AB430ACC7C4 + B4E7EFA2519A98F2866BDB77DBDB61F2B1289AEEE7E65CDEEF2F1D86157E9F5C + 0F65B0875A6ACF4ABBEE9755A7C821ADF44ADE983AD9FA233EE3A3B958796C36 + 03D35C8A35D513E7C037617F95F9860CC68F6A3419F68CE1844030C16267418D + CF15CE6EC4FEDC1759DAD08CD4D330CCCDD86D1F216C06D3C5FD887FA2703BA5 + 1033F1FDAE412AAC7270F56B591B5B19B2D14B59C4E266D37E54EE8CF818B88F + EB514EB83DF8A7CCE1437D8D26FF95592752C90E5047E6B9A50ECE8149DCD1A4 + 8F91D7AA549A34B3D380AA1006F3DB833D7AE077593A579D44929A3A7795EB83 + DF2BFF37556237B9200C0CDCE6E314BB7F2AEFFA255AFBAB86C8751051A325F3 + C6BBC625E98B7F79839B742EFEA7259F33C1F824731334538F6FA855E7931055 + 28D1AA43A5BDBFEF56A969BC7F507126FD059FFCBA223247903510A5F638A531 + 57E92629FE243903499617BE09F549E337000B141110F32BCDA095151A4A422E + C1EAE405AFAE2B3686838CFFD4854361D046995014BBD7AE4455239DFDA38302 + E7A6F14159208668224479F20643FD37ED5FFB62C7042A2DDFCD8E6475DAAE50 + 4C233599E2117E1777AF9E1EF2C2AC1747F884DC9671A81051B5D0D69E6DB6D4 + CC14D7D561C1DE362BB6F27AED1B2D09556234705503482AF68857A36CF3946C + BF81B6853F6F76670ACA49708EFFDA4BE69FB5667D207261B18E5B60502369F1 + 92E2BC9E62AEF82D65FA0BAFFB92982681DA59699EBFA9E5AF2F9FFA99B67AAF + 36E658B6392AC9FA6320FA88EEFC8197E13430C7F2D8E8E9FCE2F0546A844FE2 + FF5CD11E1EEFE8C45ECC9FE4B89E323DF4319F2FA4B4503D6FB1768A3E20F266 + ABCCDDA32339E7591D415D3D068770F2AC589193A8A11CC30DAB6D49BB2806C8 + 2F8996AEC8AC92DF98DACD2EBB7703199F0BF3742CC90FA59CE72D068410D320 + B7EFAD015D30DB7033F01742210BC61AC41463EECB1E5BA62B5DD94B4CDB5BFA + 9A6B46B4470DA28B988537E9B2683157D4AAD3D0EFD97C069237AC2A98F204E2 + 8B2AFE5A99027BED424E374E69121AB15231B7C8E7FF34B9043B640024FE772A + 8BD18AF96C99EDCA6F80DCCC58A77ED41CE2475927F72F6282B78ECF49057BDD + CCE1AED834E65A057A3CFBC6345C81D46BA3AE1FF2EF82356A32B84D6225D33C + 8C5CC328FA52BF8B1E16138BC3545DD9B2A91F90012D28ADA35E5D460AD95CBC + DF171141D5F0ED26BF68B34913A65273A2CAF7E8B6AC177A1A93FFE4C387AC16 + 6E6898628C871E47C59B7DFA56A780AC30085E3D77422F11711D6D7704A6EBC6 + B210C72CC339D0BFD6835AB8D771D9B9162BF776DEDEC43B3E9F9EE047397359 + CFEA2AE8539719E7DA75B0E9DAAF5E4B3A4A7677C40A5BA94B03E9E07C4CD6C5 + BFC68BFB1B51E46EB6E9C7D235E0B4B5FB105B60FF06CFFB8906F5182B4A82F7 + 7DB81FB90A362CC653F976615A6380F00B384338F55423CD087B59D869EBA9BD + A10D3BD2D40CD80C5DA6FEA57DC70B263BBCAAFD8B7232ABB4147DDD4DCCC866 + 04F9C7F824F6BBA7EC9356C22879DC87EBA87A724E4F7D65758AD433D1E7DBE5 + B5674D6C57AB24 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + cleartomark + %%EndFont + %%BeginFont: CMCSC10 + %!PS-AdobeFont-1.1: CMCSC10 1.0 + %%CreationDate: 1991 Aug 18 17:46:49 + % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. + 11 dict begin + /FontInfo 7 dict dup begin + /version (1.0) readonly def + /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def + /FullName (CMCSC10) readonly def + /FamilyName (Computer Modern) readonly def + /Weight (Medium) readonly def + /ItalicAngle 0 def + /isFixedPitch false def + end readonly def + /FontName /CMCSC10 def + /PaintType 0 def + /FontType 1 def + /FontMatrix [0.001 0 0 0.001 0 0] readonly def + /Encoding 256 array + 0 1 255 {1 index exch /.notdef put} for + dup 98 /b put + dup 99 /c put + dup 103 /g put + dup 104 /h put + dup 109 /m put + dup 111 /o put + dup 114 /r put + dup 115 /s put + dup 117 /u put + readonly def + /FontBBox{14 -250 1077 750}readonly def + /UniqueID 5000772 def + currentdict end + currentfile eexec + D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE + 3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B + 532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 + B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B + 986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE + D919C2DDD26BDC0D99398B9F4D03D5993DFC0930297866E1CD0A30EB76029337 + 900ECFB1390CA5C0C3A04528044F266BA17BE487C79B94FAC6D6484684C5BFEA + 87BCCC77D40AD11552035E95E3007126418ED49B68468B38A14E88E68A267B98 + 076F1C9769A5AFBC285E5B158EAC9F926F1D6C0B8F1D57D9C31D25AE27123518 + 9D2CD92E5689E0213089BD268DA5E47525CB8EABAA4B78A15AEA34705889AB3A + FFB8953B5B3482E52BFA0940630ADF8C0AC2177D907324299EE980E850F203CD + B627962F43D5A678C44243CDE97853BDC6AB45FD5C09AD274DAF89929F583CC9 + CCC24BDFC68B92111055ABA5F26D2DC67C70906F71C2957701D65AE746A60C30 + 40E6CB24B97FCDAD0487AE38A201FBF0E41BABD2181981A71940F1E707F91E5D + C8CA50CB16D8702D188E56D014D92F76CE0B52ABDB9110E32438D2BBF3E6A40B + 7B005F10BB437812CAC6ED2996F7606DC962C4FDE207FF322782C343DF44CEC5 + FF06A55C630C20E9AE1B0D1C5673753C43BA0767D65D1B451CC6380D8BB3C4DC + 81E8FD8AA79BE993218686F29D3CD925566DD587F541A0DA1B1CC3BCEA2E6C7D + 5E1016F6917A871F1BBAD96AF9E867735017119A381FCF33EB2D3E1E7093FD90 + CDB0CED4818CFD9E201A03430CEC713620BE0D3254158931FB657C6AD4B2482A + 0E7D070D7497892E9E942DF58E88CAF0C8221BF36BF7C435BF2C683A4A2EF4CB + E85820A8AD3486155A40143011BA9D76297F46DEF69ECA4596D6E4CAABF84091 + 22A96A4BC78A8DD072FEB759A68A44BE1164638B6D952147EE3C628F9A022060 + 1D1941E73310943FA782532ABB1116532AD67AEFE0758C051241E301C7E13A98 + 6447EB0180BF6799814BEA4DC0F727D0A40B7BC3B1269CDE174453D6A3C4479C + 146001CF717DE25AC1BE5AEA5F2F1C17719251C429D3AED19EF8CFF1AE213A74 + D24DB78BEB452AA34E8D761695A73179A96DAD7904530CF1A623C6F0ACE1A8E6 + E6B2E53D0B5A98B72DCF0D102E200AE46E81869D048E2FF43827094795935B30 + 3F22F65A63C4FCF42D7DD225B1559DA4430B476E2D198F649658580EB8A1B734 + 3656C1FF865BED7977727D7BA6C0A1BA5C0BB2CBED52C2EF6ABBDAA425EF91F3 + 06B1C52DB14BFD9612E8855DD1D304114C5C850C0D0AD92D5EC25BEA4A5B52C3 + 264464DCDA2DB2CFDBD8B2A1C40A95CD3E3643CD5E30DA493196985A187D2D1F + EE76321B94025E298D2398300135356148793CB63D28503882041258DE5576CB + 225F2EE7BB44C9D70962559A2DDA695EDFCFADBE9B0F24A881AFA65209564FCE + E6389E23F3BBC936D1863D90B5B640BEBDC1296B1837208F90A952283506AB0B + F48AFF329C37E010F7E816C06EBAEA6E2C58B49126B4AC5C5885E08302D8176A + 5FA6C3A1B61976B6F998C852E4BC82A5D0F2B94F61D8D08AD28DE2F94D7E4AB8 + 573120299C03E30473EE6092A62369B2C9B4CF65D96923E245E10C6D2BFBDE8C + CB612D06177E0127195A413C1BE513AB02A6F8664F6E90360D569A3AAEC253A9 + A324376980E2154364FE2967C8153B474DC8A09744CB499C2CFD79C18E0A5951 + 776AF9616D80ABEC68E7A498767828528E46F58A81D28B087FDDC8F4568C98A4 + 644BB9CF860A3BA392D4BC6EABD044AC5721C02D238FB32710457778A5BED422 + 37BAC54C02807FC39C7119E2A0036FEB4E149040EA12B3162C129C932BE37E91 + CAD03BFF02041F51E46A49687A7ED101A782AF3F3D82C36D40A0061EA2C46E19 + 4154AA6B280002D981A479A6068D669872F2A39A54110AAF68FC801D58585A18 + 7A1BD3B5CB89417A62DFC786625405E52E74855853B5F21564EC7ADF6B489725 + A2E5E44966F2D1D1121A60D1E5031F5E3A2BE4EF2DB9DE4D0BA1B70119E27A0B + ACB2F9A65F02772950DB491CB36F9469D3EA2BA9881895EA9E2A71DE80C6E04A + B35130371BC692E3C370B3BF51CE5A5275E8C0C860FD597CCB8EF78BC89750DB + 3BDF403D28D8B42F786D7E041A780E93D03FF6A0BA2714596C799889F41EE6B4 + A00B23E5D87A04A1D05569272199D1EAAD1F316FBB8F83DDC5AEA9CA1ADA049D + CA105024F7612E5EA6971E2C8D3DE70517C26BF583497A0FE8873900A5AEAF75 + 72E6D13C9F70CD980474DD5CE2FCEB75272E377AAC4709ADEA39869AD9C337C3 + 785CCC20D85E58ADE45696C589BC1AF6C035BF280E326A6970808BA986A498AD + 989C38D700D1A51F771A8979B871BC0F9022331E956C47A445CBA9CC0C1A5E8A + 0D0FDF23DFA67A8DAA5CAE0EA80C5F70916FEE1D54292888464D673DDFD1F626 + F37A1418B698396A3DA8B8E8DB1AE0F76C483E948C766FBF998A78F09529ABB2 + 09FCF371A8CD760FE1EF593B090633EADE96CD6B836050771E731AA56AB0E5F9 + AE4338074FEC99D09818E76A53982A98FCCC259B05F42061D62DABD443B8E581 + 94BBDE62C2A2F638C8FEFEC079D3416016452C1D89DAB31501583D714D94E295 + 780143AB78C425C107A3A10D0BA4FBB149A043FBC35227FDB1AA7C802516018E + 73A3DBFA80601B9755136C5B6277989B617B1F7F337F483273814AAB5A97AB6E + 81CFABB681E87691C87B4EE6F01073A387FC03E58EAB9058D1EC45C877CA6154 + 21FE826FB3715D542CCC9B792774C914DAA73ACDB9A960F3F7BA16C288C28CCC + 232E6067114261917F42BD37437C011B9E830BACE60CFCDFB1D18050423DA95D + 3AD776296D566599A1D089F50C20BE8EE33395CB6CF2A4EEE54442EDDF844B5B + 7E3FD8F9AB5F48AD36CC6A0023990776050FC607AA3902149AE66A057516DE63 + D5C5E7605B574B85FFE4CA4FAB4FC069FF237B2664CCE2D5D2F89BA071D81ABD + 911D1831DF0E05D0A0CCD2D3ABE0F4E52E529F2047F67762B6F30B22FEA887FC + 14425A80944A7D63402A7A7934F493DBE6875D7D0A1DEF167FE3B37DD7DE9E16 + 38E26EC0F8D8E92F4FC62BE06FFA3C65A09863A1000EE929BF984456D424B519 + 90FD75DF937C8DFF1A652D9B200431753D65CB7DACB4CD44D98F87B0987A7FEA + A1EE74C2083120DF71057AC4793804C09FC4422D9B3C69A6497CB2B4B7C95F45 + B8F90B98ACC3AA54E487A02A19304C218013688532771D38606024DDA84A5216 + 4B9CFE750B728F7CBD930F3085D6FFD154641E88A078110D050CD0777BAB2511 + BCA801F6F1D51C30EC051E2DB12C680105B465CE96D7690892B1263C9E285893 + CCB7BF73F7B5B58D6D63673B86A1197B1C09F5C46180748FAC28007F8FF7A37F + 78785F1BEF17F91C3E4B5C3645FF3903C258198D47EFD249C4247210E75F1AA5 + E51944E3862BA99C10ED1C6215996CFCBB9D4613E82496F6C69FFCA7BB6115DE + 3584E0594F1CA295CB481CB2390F8970A532EC33DBEC73B6B8FE + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + cleartomark + %%EndFont + %%BeginFont: CMSY8 + %!PS-AdobeFont-1.1: CMSY8 1.0 + %%CreationDate: 1991 Aug 15 07:22:10 + % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. + 11 dict begin + /FontInfo 7 dict dup begin + /version (1.0) readonly def + /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def + /FullName (CMSY8) readonly def + /FamilyName (Computer Modern) readonly def + /Weight (Medium) readonly def + /ItalicAngle -14.035 def + /isFixedPitch false def + end readonly def + /FontName /CMSY8 def + /PaintType 0 def + /FontType 1 def + /FontMatrix [0.001 0 0 0.001 0 0] readonly def + /Encoding 256 array + 0 1 255 {1 index exch /.notdef put} for + dup 106 /bar put + readonly def + /FontBBox{-30 -955 1185 779}readonly def + /UniqueID 5000818 def + currentdict end + currentfile eexec + D9D66F633B846A97B686A97E45A3D0AA052F09F9C8ADE9D907C058B87E9B6964 + 7D53359E51216774A4EAA1E2B58EC3176BD1184A633B951372B4198D4E8C5EF4 + A213ACB58AA0A658908035BF2ED8531779838A960DFE2B27EA49C37156989C85 + E21B3ABF72E39A89232CD9F4237FC80C9E64E8425AA3BEF7DED60B122A52922A + 221A37D9A807DD01161779DDE7D5FC1B2109839E5B52DFBB2A7C1B5D8E7E8AA0 + 5B10EA43D6A8ED61AF5B23D49920D8F79DAB6A59062134D84AC0100187A6CD1F + 80F5DDD9D222ACB1C23326A7656A635C4A241CCD32CBFDF8363206B8AA36E107 + 1477F5496111E055C7491002AFF272E46ECC46422F0380D093284870022523FB + DA1716CC4F2E2CCAD5F173FCBE6EDDB874AD255CD5E5C0F86214393FCB5F5C20 + 9C3C2BB5886E36FC3CCC21483C3AC193485A46E9D22BD7201894E4D45ADD9BF1 + CC5CF6A5010B5654AC0BE0DA903DB563B13840BA3015F72E51E3BC80156388BA + F83C7D393392BCBC227771CDCB976E93302531886DDA73EBC9178917EFD0C20B + 133F1E59A9783D4C5B131F8CA382909A8C7274549BF8F3D02BED89C2AAA0CB40 + C9A78AA980B2FAF4DA4FCCCD53B411E8AEC87BF9726470F0A623A86F1FDE049C + 5FCDC80B88A9C057878D54A6467C3336637D253796A9ADB50A67F03CBC7C6431 + F57ED0EFE5D66B301B8884523DDB74063440354B245226786A049BC18A32F2F2 + C30BD1E40272C7BE8333D35316A52B6A581632D59FA94253ECDE268CA209A1AD + 70CABF08217906289C96A9A631192DB9EBFCBE3B1DEFA44F756F4907A2204CEF + CD01892C86 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + cleartomark + %%EndFont + %%BeginFont: CMBX8 + %!PS-AdobeFont-1.1: CMBX8 1.0 + %%CreationDate: 1991 Aug 20 16:36:07 + % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. + 11 dict begin + /FontInfo 7 dict dup begin + /version (1.0) readonly def + /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def + /FullName (CMBX8) readonly def + /FamilyName (Computer Modern) readonly def + /Weight (Bold) readonly def + /ItalicAngle 0 def + /isFixedPitch false def + end readonly def + /FontName /CMBX8 def + /PaintType 0 def + /FontType 1 def + /FontMatrix [0.001 0 0 0.001 0 0] readonly def + /Encoding 256 array + 0 1 255 {1 index exch /.notdef put} for + dup 35 /numbersign put + dup 40 /parenleft put + dup 41 /parenright put + dup 45 /hyphen put + dup 65 /A put + dup 66 /B put + dup 67 /C put + dup 68 /D put + dup 73 /I put + dup 76 /L put + dup 77 /M put + dup 78 /N put + dup 79 /O put + dup 83 /S put + dup 84 /T put + dup 85 /U put + dup 97 /a put + dup 99 /c put + dup 100 /d put + dup 101 /e put + dup 102 /f put + dup 104 /h put + dup 105 /i put + dup 107 /k put + dup 108 /l put + dup 109 /m put + dup 110 /n put + dup 111 /o put + dup 112 /p put + dup 114 /r put + dup 115 /s put + dup 116 /t put + dup 120 /x put + dup 121 /y put + dup 122 /z put + readonly def + /FontBBox{-59 -250 1235 750}readonly def + /UniqueID 5000766 def + currentdict end + currentfile eexec + D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 + 016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 + 9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F + D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 + 469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 + 2BDBF16FBC7512FAA308A093FE5F05C11F9A72F5DA508C30BC4BF52C8B1EC5FB + 7F9DDDD0964A6D59193A389D490DAA6F6ACD02CF71C06802F3AE5A001F2B3A6D + EEB60E9DD26DBCE1D29C825A9BEFE3A6572E70DC7B60344C3E0C9C77ABE1804C + 7ED61C544F0B4A3D6C7662DE8575C07BED3F6DBA7D64A9C8613AA152B74A140E + AAD9B66E0FAEED6AF9D1820F361C1269A5E90519A3E6D40782E06778C0AFAA30 + E8CEAB87054C4D156C1B14B4E8471D78648FDAC70A3B8ED474FA356393A77420 + 4211F60E397D2FEFC6A8D91A80C84EB9E38E663249FB91D5C8A5CBA68BA04272 + 5D5D42497E1CF5CA1E62EC2B139F5CD4D6318EBBA7AE28614D2D88709C2A3762 + 611524B8A1FFC7B0FCBAF77AD8159C354F4887DB1A27781DE0A4BA7DF2CE2025 + D9278CED48584E8E6BDF30BFD24284BA1DF828B637BF84A02908BBCED67372C9 + EF44711BC2B1DA343C8D9D27A9745525C774F5D639B7AEC197CEEDD06FD27923 + 35ED0D402AEEB51134665A47847429D91CF419CA9B09DC905F610F8DFC54E606 + ADCDA19D5CC68A7BC7108EC9236C64205B23CE68B9BC38EF3E5BF9E0E6ADF404 + 7365C8D0436609438C82EEB2F356F79186DDF6C1C797D3C278108B1767D15178 + C4C3E8ADC2482BAB9536AE8419E5CF3EE1B6E53BDCE2A83E2E485F496A562C10 + B3F5A131BB19D1E5414C86C5F995521076340536E10613E42779FA15EFDB451F + 53495CE8EFF239E4EC442E1439594549D45F5276F93D496C9AC712D762D0B702 + E894290BA028837304AFDDD8BAA6564E9DC307A14A7A206550FADDC7784DE3BF + 3390188BBCDDD929C82B1D7B529553BA75ACF5B385D31EE3902D96B2B5DDFFF1 + 9F0F90FD791E54128C1717F313486896868A34FAFF22E23CEF046D02C09E3EC1 + B8CE4D8ED824C9B23EE2D47D5CEB2395802C52F2323BA272C75DDED2FF9E7CF1 + C966C747B826165E51FB1F5B8FA870784A39C6E8D3BBA8676079F21DDA4B1C66 + F150474270B7707DF27F36362BA7834CF0AB1747C6649D0D72215424A63F894B + 29B38084C2FC300A4209171E492E2931803C6BD7369EEDC4A2F2F21565CCF50C + 69135D50C1F3B5CB26E2C36C61D6561A332FB10CA35CA5048E60D5A5F5235A9A + C0D268BAB1235E90F54AAB4543D071E3E7F646EF5920AB3C75F05C950F210979 + CB834200D0E419C488213824B3F04806CDA099DBA781275703817CFCE4F88772 + EE2646E00A33AF43B1FB39165BB55F6C4B3B4B1745BB8B8745DE0EECB14C2FF9 + C661CE7560CEEA98804B1E1D07C9D75E7DA313B80374A3581B8F878837DB17CD + 4247AC6D1A7488DF70F39EFE0E1154F3647E4ACE2D168E472D62E9B2CFC21E12 + 0835CE09AF40D9746087E124E7BFD431AAB93521F87C6C708844EB21F89EDB44 + 323CB3C87E67BCBB76656FCB354197D9EC4782A7393E0AB16CD62895BE25F8F0 + 4D752576CF9461097A5777ED54C08B66097AAFFF0C49EF9C38EA25C19E379515 + 63FCD59A9EFA62660D3E84FE5124EC9C3276B4CF638F9AD8B9EA698F5EA593CF + 35E74CD6D860626DA787A92C682200A1F3382B07EB60D1A0EE8E0BFBECD75FB7 + 52AC3C3FC015B16E11D23BE04AAE9C55FBC48E140DFB16B6E72C0498F6EEA00D + 37D7026E8F97BE8B676AED3114DB825BD885C17A09EC484FE41791096186330E + 2EF00210E85F287FD2680FF3BD4D1B99F8CC079B46B4158273D24D0D69C5653D + 53FD3A62784ABD41AADED572D1CDF3617778F0922DD4D47F64910DC59CFCDE19 + 6D72CAB8C0DA9681F6773ED368FA580B69F32050620FEB09958D4C2434876173 + 53F5FF7045CFE9461414D3C000A33004BF3AE0A66B32177B1973596C5610D53D + 775023883634307029626F15913DB8E0ECFB7D02E15C847F345F35CEB765D9B0 + B35375BE38C916C7F24AFF66950974569DC77ECAE5EA9E0EC59C65816ABC633B + 3B578820C391AD8805000BCA1FADAF3C2E654FFF2A007EC40BC69D77191141AC + 0CAFCC6FCD3EEB1D8B9CAC4CDE8212F8EEBA93BB9DA6C1BABBBCD0480799E851 + 086ECD367E4A4AD50CCFC905C73962A27E70C0ABD83295E19156B59A2265BA7C + 9E924A10D2E9529A1C29A14ADE7F4D4D465A1296EA837AAB63D1426173B514D5 + 26EFFE4F50E654B974CF3A0ECEE7E24C87B4D84EE2FC223DA46E008AE75A59A8 + FB73A3CF3023E7BD4F80C36E7B44E753CEBA3D68EB8BB79182C1D1417A9AC92E + 0804BF00D37450CF1A0AF0B574B8E42756150D0FDD4A8897F4115FEFAC6906FD + C69304CC97BBC872488D00C70175F3CD60114C842ADD01AAE2AF0768E44A96BB + BD180065A3A81241611E4F3B0F7FB480D2640A78DEF3892EDDE6AA3E3B0EB3DD + A286C8D18CA993193D4A985EEC60CD55159AD31A24BE757045F5F57EDE54D4BE + CA6C50709934B8982F164A42C5665A85545B760FF2A4DDF5E62748006F0AFC0D + C4F90FB75FBB0B6F4C716670AE5B5DF363F81039C3E86693CD31B05AB758F66F + 3B585706F4DF28E5179B1CE4A510BA8A222BAD66640B4225B36B5DD1723BB716 + 0D4E07E616058ECC3328C890DC7FAFD7F2B8A1AE0202DF8A425E622EE53A7CC3 + 5B51928AEEA1C6320A487DED432456A34F9CCC02646454B26C2EB83D2FBCFF49 + 016B54774A65B9E02396C41D36A0D63AA1A51014314ADA9EE9891FBC7A37E7AD + 0E928D0A2A6261A6C7549E6B8090A4FA83DFD0528F7AC3FD810D6D81B0C7D3BC + 65F1865180036F8CE4EE83ABA898EF0111DAD2A182A48713548C88C6DCCE7289 + 7683514841B688B139D638AF74DF0678D35EF07B35FF29A52F5C8A248164137A + 4AA74BFFB54A8FA22982A62D9082BB9051191749A362CFEEECC6838184828059 + F1FB7D1A9E38E0B928273748F7A0F31CC2DF69D87544B0873A7AEE250DC0909A + 5CA8482C6A3C61609AD597B25B7B1BC26BE853F40728DF615C395998D3D73D77 + A88933C6E382481A37926B2E20BFC728A770F106E59D3565A3BB0C561F6535DB + 37EED73CD2E788F5F276768FC7AA141017DE43F30AF771D9CD7EA82FC56077C8 + 2C171481A565FD9BFFA12C5A06F8403622094537B5BB31B6220B335ABFA2A24C + A7B36A5B72AD083D0BD0BC96A05B70B4F149F1862B5874C4E6B6866AABA912A7 + 117788E7FA1989101F41C28BFDA4DA79958D0407EE8AB435459396CC97CD0D92 + 5EECD8FA654200D455F08D457B1C28999BD2B2F654F06CE7962BC173B6EAE6B2 + DDCA8A4BB4A7867CAE0B2139EE2AE8AFDAA19B0607522C362717BFF456CFE3C6 + D7BE3F64B094E2F43754FA843EEDF8139A6850902E51834864B1C57279397210 + C9193C8CD29C6C1378B16A514156383C09F6407A27D6D205DE421809E4B926E5 + 87131B25F065397312027EDE49D843DB2527FE97E171B9EF6E66FC1B4D5F32BA + 9300A520A7B4B2EE91086595B4A08B31E25DACBAC0D6B05CE3297B3482CDDA57 + 448BA0E62C650AD414936CA73314252239D6C795BE0FBBCE2C4BE2684F13FFD6 + B5165A3F96871F50CE34B64716C085046CFC1746FB8609961195F00B535621DB + C9E1BA08FA03185466190C87C42A0B658321BF0E3220D876195C4B1905D86161 + 548F77B51512B460B56E4BFF8C0F5D3A7C15DA64AB5658D8F63C841CFDB0C832 + D5EDA3872A6CBC5B6B1724878B8F52253AECD6C7DD71A9878E31161009B1E2F6 + DC378FE6A0E9F44289DC2E84126131604A804884AA2BD4B3858EE15AECEB1C85 + 9A98116502F53BFA29062537CBCF690F36F413411D910ED3DEB1F51DBF2C1932 + 9C27B1B89DC784B74D8B1733BEA4CC67FBB72FDB95CA7F28AEE3B5707FF492F2 + FFA18690BC434C6250B56745A203C8DC6DDBB8F54AE973A2A6351D849F4AA310 + 96DDD1995412C03A12C821E77316BFCC1046A134762E1A4A158323AD32DCC566 + 51F1D4704C2304B9AF234B458BAAC4AE9A3748B0BE23810668C185D851DD30AA + C0E917DB16328D1241289683BA628537E59B1EFF4D7378A31CA2FBB1DC101BFE + 41BC3C914762A57CF428CD67C123F6AD39C5F9561B1F5A645204868E085D9552 + C251288B940BBCDD571A94DEC7EAA4462765CBE3022EF04750B9B0F2E51EEA1F + EEE537E8EF306F4E36F1ADC852D0ED87C376745E01EDB7B0373C07EF11C841A9 + 613F63754199B1435966ED11119C9B2B490F4BB80832A0119921FE07437356FA + 83F3C0BFC235399DB9206AAB609584408DB7655CA26C6C155F39F192D1E6DF94 + 3D679A9CFD0347BF7E5BF2C2A75BC83C419411D6DC031B26C498058CA0BECE94 + ECBDE113B417C93C5C80BCADDED2C03E89EA9A3D51B28048C942AC46E0ED51E9 + 97243E9F485814CB8F468E07B0332F2B9A5F3F15EDCC5644DB75D3C5F24476A7 + 44863FAA9A6D0DC81B39CAD92045EEA5F7D9D40C793818F73D5EE3C8873E027D + C09B3C0A4BFACDF34E4ADEAFE51FFEB9B1209534847D66F77AC42668660E2AC5 + C2DFD7A4F94634310A2F45A92D128650A3676BFB311D696D4DC2601BB2CF9F45 + 0297CDA06D40B79A7D7C091E5040CDC88E9CABBC604ABF835E97393FBBC068C4 + F3BAB93A738A400A15605F611D798EE2EF6B1E52F0F7ABCD7767F06B900E0D0A + 44FBADFE1CC0BF3A744647B87342521E58702774D3B61694F2A17D888E7BEC67 + 77BC7F04BAE84BCE09A639EA8E38CCDD2D4229AFDF05435EB3CCE2B25F448275 + 5DB94606D1CCABED46A63664BEB419B8FCE32DE495BF5990BDB23BD02A165524 + 58163E54A2C0D28947CC1617A702612B9BA9471A376C25D7F397FF8E49586BE9 + E79B81F51B2F0742B5417CCC2F817BD14C4CB57D973CEDE060F98FFF4C5A22EF + 1BE8D9B729E6EEAA5784E22EF575B4952BD1988F23D91EC7EF307AE3B653843E + DEF62FC57C5004626A2700A2F8BB99410F4BD685201F39218D36B39CCDE70F00 + 042B4525219FB21CA525ACD326E9A0407FE4CB113C29C7CA0C1972CB9299F0B5 + 8719980445B39B05FAEF09C22E383E71DB431ED36F4EDD724A955A22B7931F4F + E6E76AF2EA22F9D8B9E0C1F913EA0C83572B79FF964E9EB6F525B122D25380BD + A28214B9A38C5774E6BBC385A60FAFFF699B537F72069BCE91CDD5251B6726BA + 749E087AE9B2DE3F97DB908D3C37A1B1924E6BAF8C7053FD8B50E166C8749610 + 3B2DCCC79C5E25E7EEF2D7C75BE58661AF285D889868BF62AB6245093A4F3A3C + 00A3F7152E4BEC82721DD4DE6129B23D1D5B9AA89BAF42B2DBF96570BE89D3CB + B9A6C422C1B9939980EF2B678B1367BB57E296DC988648DBB5B98DC3AD9FF930 + C7651738BA98E86C545CE3AF8BC8CB61615D5C4A2CA56C55DC74222CF6752902 + 9E3072C93654BB9793261AF700B76E7E55C44886490E21C11A474427E42F4B9D + CDD316DAAA79CF8A5E2FEECDF79B70A047B85823A44B7721F805142A333CF93D + E9EAB205F8911190541D461A1F92FF41F206CCE3D1D1D173A6EE9CEEF84E6F0C + A68204BBDBB8B3A456707FAB80B23E28E44A0F8DC74CF75915ECA61276013227 + 54B78990EDA651820262F12B3AEFFBF60C853E96FA818CEF05B5A71F89DA1825 + A7FA037F01AFFCB751232AA189D050F40C69A702507DBF11054BB7543E86DF53 + BADF1076C0371F30DF9DCD4F5AF1FE098B44ED894C46DF030701BAA90F3B9F5F + 56EC898BE7E3F37A862297FB24AD722BC2898374EF9C2061E75E34A0F7A459E0 + 2AB8216A301753466198DD943D014EAE49C0951BDBC5CC7EE1AF3E1C47A2A4A8 + C593A2F57126F0A48DF954AEBCD5DB30CC9E897299933CC7E4EAA22EEA4BD8AA + E4F329458AE294F5508AEF2A277DFB9EE2863B691076A068D36240774824D798 + 4415986591580D106A665ABA56D153EA4249DEB1FD205934696FF23DDF0A05AD + 752229DCB34E049C7CC4195F211B58057D1D99048F458E614BDFC1D1779D6B55 + 2BDD9E8BB127E60A13414895908404D8BBBB3EBF3EAFAFDAF89A4AA8C0D6F9DE + A2BDB9236B3BAE587C920942EC47820087F26CDFEE0BF9575E9EF69989E6C0E3 + 5B2D2C350B2A2BBD19EBDCA38EDCD2F7A07DBFEAD80721BA656D683E6CCCECF7 + 91F3E67D7CDE41584354EF78533D32430FBE53A137B616D15EA2DF276BEB9C18 + 9BCB668D28EA130117CD408853BE7C0AC5496328F6F5AAC80F0DC0863259EDFE + DE08FB8C7C58310BAA5DD81D6EAFB6B65219FC1F7F02B4A61EA8A43E9F03CF8B + 1662565FA5BC8708639060C3BE0318DD00BE6762B623ED9CCBAE354A09AE74B7 + D641A99AA41E4C2202BE790B0896248A770A63A1EC2D6DD9CCB7A1D78A7DE2E6 + 9CC4639E0AFAB32321607D26F3DEAD926A6A28043A405F2C81A3D19A056BA33E + AF5D3B7877F370EF3EB27FD0DB27E2BF0C3AC7DE5892FAEBB9BDCD3B89DF4ABF + D02C33ED4C98B894E368F84C9BB3E3167EC57EF7CB0A9AAD1300ABFCFFC853F1 + EB959D90F14274D1CD440B54B2313E955620B16708DB9AE68EE40503B58A6636 + 3DAE47715B1EACE44181A11C329FC799890E12A133373368A7536A70F680DD80 + 23C94074B29081EA5CBD6B515CA4BAD1BC1235E7F1599C41C397CDCC992D7A28 + FFA7492CD017B6AC3B109309F6A469933443EA91745381D33C0235CCB9F09306 + 363D27E4CAD6301EC479B253248D61CFC2EBCA5F2CA986365992B755B70331BA + 45568EFE5579B81252AC9F32BBB234E6DA55C2DA9C09E82B65E9D0665E3FF9DD + 33051E27A7C43DCB5DD41B3A7E1AB2DF6F410E7B76779876CAD8E37566939949 + E9E0BA6017E8EA893ABF78DB696A6CC257EB7862576778598141DDD35E8BA409 + AE8AAE4AA5A415F2C122E7B6DB9FF9BE4F70F9BFF453FE090151611CE74A3EF6 + EFB3FE5A1A37CCFCBC0493B23841EF133C86E015495AD7ED7DAE414F4ECCA6FC + 6ECC920367F9A77CDCCE12E25CA61A36EE90D6C305165CE409C1565F0DAB1517 + 47D21ED35FF3057BEEAAF091A570FDB26082C8665494483295EA4DF7AF0D5887 + 61F9938B1B930313A2776EF1926557DFAD36D24A360A7302B2777A7BAA28C2BE + 8CACF2AA796D09F28F8759943FA55F1BB9B5671B1AB6B0A216C4A73763D9F335 + 201405B2A347A7C378CB5F829E582ADFE5CFADFC107865B1466A08521277E10B + 6BCC034541E1DF6E8ECB3E6DF50D7BE638218C7633E3C9F545B48E68202F2050 + 698591CC099B646EAE659BACDB65C46232230BD5F3492F9C29977EB7A0215F24 + 1AE5B7A580D5301E2D12809928672C43D9297FB13651148B422B6C6F31E1ACA8 + A6D4F92E9050C8A52F1CA336481343D82DD0621A460286D721EA7F46F4FF176B + 994CD27F735BAEEA3B6E5016E3F5A2327A968BD4F5F31A4806122E828F0BD1E5 + DACDD251B129FE4198D863A51056728D13C2708F5E2BD0405D9AAB762F554EDE + 23470D8935565D83B93BCD8095267628F3D558CC8F7EF7A30997B3C7471B622B + EEAFC2D8E6F416907457F79AC760B357CC9A0598408B8F597628000BA8F9E268 + 43DAA38E8F4BE6588422DA474CBC929B7059BB0A7D4CC566EB088D6905EC0488 + 75FF1951029DF0A318D8E2158F68710333F3274B070C2278465664A427A8C96B + 48151645FA42C3DCB6853060D75A2BA2339BC141507753D3C9D01EBEE40C17D9 + C04FADDD98891A3FB93983F875F1ED877F2B2BB727A6773DE8F1156FD6095779 + 4B28C35A782034253C04CC1A149A35F73BE5C9C171981C9EC1248AE9E7274271 + A028E02956FF6C5971C1FEDB9289D90C97C897E5600BF8256D10A675E13BDB1A + A4EC945EDAA2CD8758526F9196D721CA182608193A6B7E1E585C8F27C74CB5E1 + 6C72D4A3FC4F1312CFA0285D999FD0ECFF66DC81A16C317391E71688EA68B172 + 3454E2441508E9E0FED808ABBA7917917C7B865FFBBFB7BBF2952C133F3F7C2A + 60ADE284338616FA6CC9772AA72542DBE039C353FB0ABD2D450C6A033F0F0287 + 270ADCC13E4193E76382BFD8771CD808690C04301672366124371AB175C38BC4 + 3B0B6227D4B5888735899512BEE067D32086E807BA81293D2E1132EC329143E6 + E9B7A3B6319A46486E50B00ED37AF755F5C02401D4406C93717C9DC8869D4C61 + 98E9AC328459CCA50BD29A8DD04EEF93050131C8B29471960E42FBCC41E77BF7 + DA8214034A28F59FF58633D26B471CFA4E986AF24B29E6DBE01A07158363F07B + 8CFAC36AE07244E5060EAE8227E648509F452BED881FED8ECCE18A3CE5C5622E + 6ABBEA92135E5645952D8A4F35640A5B5C35D4DB9EBA0C1EBCAD9E0027B696D4 + 9E3A8FED985326B91EF2DACC7D7AEA5F9783FD20BCC8CADF17E292EEC745ED46 + 6BBAC9CD4A4C330BEE50C8612D9D6B5FE72B4B4AB404DD9FE50BC8350BF81C86 + AC1E6D882BB5707FA1AB124D31BFF8BF7D435FA779AA7808DB7267E521E418F2 + 4E199C64F7EBA5D8360F1A171C7414C4CC40DA23EF7BB836B392317664FED9C4 + 5C6584B6FE92AF10D7A318DFEC6B19954141331BD81DB953122C5795F0FF8EBC + 5346A8FC4565A01DF1966133A057776862C28337F2FF1DC9DE27 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + cleartomark + %%EndFont + %%BeginFont: CMMI5 + %!PS-AdobeFont-1.1: CMMI5 1.100 + %%CreationDate: 1996 Aug 02 08:21:10 + % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. + 11 dict begin + /FontInfo 7 dict dup begin + /version (1.100) readonly def + /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def + /FullName (CMMI5) readonly def + /FamilyName (Computer Modern) readonly def + /Weight (Medium) readonly def + /ItalicAngle -14.04 def + /isFixedPitch false def + end readonly def + /FontName /CMMI5 def + /PaintType 0 def + /FontType 1 def + /FontMatrix [0.001 0 0 0.001 0 0] readonly def + /Encoding 256 array + 0 1 255 {1 index exch /.notdef put} for + dup 67 /C put + dup 86 /V put + dup 97 /a put + dup 99 /c put + dup 100 /d put + dup 101 /e put + dup 103 /g put + dup 105 /i put + dup 106 /j put + dup 108 /l put + dup 109 /m put + dup 110 /n put + dup 114 /r put + readonly def + /FontBBox{37 -250 1349 750}readonly def + /UniqueID 5087380 def + currentdict end + currentfile eexec + D9D66F633B846A97B686A97E45A3D0AA06DA87FC7163A5A2A756A598FAB07633 + 89DE8BB201D5DB4627484A80A431B6AFDBBBF23D4157D4AFE17E6B1C853DD417 + 25F84CD55402AB88AB7EEFDEDBF2C2C731BD25567C53B474CCF739188A930039 + 098A197F9C4BE7594D79442B2C8A67447DE44698321145D7689B91EF235EA80E + B600AA8E238064F154284096C4C2554EFE8DDF13AFF8D3CE30E0999375C0FEE6 + F992DEA5FC3897E2CC8B7A90238E61E41622DE80F438DD994C73275CC52249D9 + F6686F87F394FB7BB668138B210BEC9E46415A1B58C990B81E7D7DD301143517 + 4C2A259D2A0A1E200F8101469C10D7D537B0D4D39296A9AB3F132DA9A3B459B0 + F850E2B3A03BDCB35AEF82285D19C38F474FB414F8EC971B994D1C7DD753B271 + 2B71549DF497C665DF0F266988209D9EB616E4D9BA229FF984E7A886DB01FD21 + 48ED2E4859FD6416C2CE52537464EA884C8C9C2D1083E2B83BE4B766474C23B6 + 6E8EC5003200AB10514BB44D14CA700416AB6B2683E80862E7D5B49A05526A32 + 554BB23AB8B0824BBA198E3825CE82380CC0FECF46651E3E5D77F09465E73164 + 20342822F29572BC7F73F2C3BF95ED3BB6FDEADC20C6AC866C4F2C679594D7E8 + 8D944704A3C5D771DC39503BECAB89F34D8CDB8FDB91AFE21F3F0260D05E90C5 + 73E2C13DFA022C4522E5918EE25038A0498FBB530DA33B0AE238B1C6ED03FC04 + 2BFED8236E07820C5BAB411EAE1B31D93A2FA7C374B1725FEC359ABCB88E2C89 + 214529A263D795AACB0B95A3AB2F4E08EF350C282CE521716DBB06E5B8291B3F + 5D4ACA230FA192F64BC902A4C8842C0F916F92FBD002ADD408BF0401D0284FBB + F05D4C6DB631420747CC902C5E1617E6573612FB26C8378DF41FFB5048D3CF06 + 4893DBA48EF4B043D760F60C75712169D16C83EE020C45369E443E853E1809DD + F395B812067D6FDBD26111B34F42C21036AF952D0D767FD17F6959D9FDD46005 + D64FFF54772B50BB9B173AE79702981F58F9F235C591F476A31852174DF0619C + A470359153DC32610E782B204E7945515464DACE9099B81EEECC7EBD4B5126AF + C3FD9DDFB329AF1C95C41FA4A5F6958869509A23BD7210386329771FA46FF926 + 0E54AC35106253EE140449425A8670E1F92B178A02A58EB57540F4BD8110E548 + BB584EA6D625C5F5FE0124A98E49915F1A1B95D2125874360EED1C4379FEF3C6 + 90E5780C20309F11F2F23FAD635C44BA030B39EFF083A3ECCDD2641DCF867B7B + 316FCAE51DFDBBD793046507F5E3434E5A5C33540BA2AB06E08D4B11926A913A + 18F8CC000F6BBA53632542D17DF5DF474BBE5FA8785AD1479A3823A1B2DAD5AD + AD3196E6109ED04B81E94451AC1360D4299BD4E925D5E4B9C117C0F8B5DE5F09 + 17ED349561126C644EBEE83C9EC086173B1C9DBF6F966659C5FD31F8BFF69750 + 0C837AA549B48C1AE06BD1CCB45DE4522C460FE8F35EB44123049A385B8AE39B + 7599E426ECE25918E2BAA3362EE6C6E4895414541CD3B3DF39BDD1B42BD55823 + DC5050B9986E6B163832362487CB4396C464DBD31FFF82C8610B3A8F4BDA2D82 + 87E2F06B01DB3F19D61C0986D121CDA555A85DD4B53613563C4D5F2ABF998FBD + 0D33DD23DC2E07B46670DDEB638C8CC60E74EF2088B56D0615552FA06E36F83E + 841A3F7D44CF8D604B5747E9DA7B33462AE5D5513243CE09777697DDA6049AD4 + 4B33EB32EE1A37F75307B28FFCFA64786E6210118FFFB80077023BC9E19F1C2E + CBCF6C19908C0DA182644A768A2CBBF12B6667A2BAF970381FA40FFEB4A8732B + 8DD28F7C815F05BEDD5E9EC4250D14C917F0D66106EF2C74876522B7B4CED35B + 4666E2A5D9583F6182F8CC6BB0D2783E617477F4ED5724838D9BDEE33C97ABE9 + 3964282846C02EED00545D6CBA6269ED8D77D6C2D04F2D47FE7519CDBEF7002F + 50213F937DBA4EB82C358025DB5C81C8BDFA9AB79B2F08D4F1D0E7630EB53078 + 6BBE097424C07BEE033411E25A06AB992A044A80423CEF63A4DC75C13BFBDADA + 5966EC7EE5237AE5AA4D56A7BBB48E45945853CFEB250E535E167B252BE42CBF + 6A06875B7A9ADAF52D06B8EACFC7502D9BA295FC3C56301CF703C7C438BD772D + BB231687C485073E11A738EF710BEDA9859E0B2D720A8E607DD3A0352A758AA0 + 247D94583A1C2ED503504F778FD81AB71D6744273434CA58EF7A97DBFB04F935 + D1221051526E541C068C03DD81E34BAFDD967174D4F6D9C212FF9A06C05B370F + D93BA916C83CB307EBF4317F12D14797207818FE646305281D5EDDD57271BAF6 + F19ADD980CA21B3109B1073C1C36219CC71CDD3507CAA508308FDA1FC81AEE65 + 9A73AEC179EE0C5295F7BEA7536CB7787E7CC600725FC298E5C89668C48426D4 + 6FA4E99C21E40C6DF2D9B7A22B9C24AC4EF869618399ACF98BD554C820445324 + 548520E4E9046A7B1F83CEF5FFABC15A40B04700B73AB34C5056873B7A7FCFDF + 06E9662A9BD40F085066A35F238CC66A874D704DC7A3550EC5C34D24876F0921 + B0E8A36FCBAF178637BDC9E42D9356089EBCB2A261F582A217EE75C9AD561A66 + 4214F7A69C112A9A4A0DDE5F5B3EE8BB8ED5621C1B68098CE0837C482E6B8075 + 538E2BC85CCA098298ED103B9544561384D2D6A90B29997E9B4D12736D13768A + B6AB69295F52A7D422818B3EDBCB3776F20C8E7101669B26DD7C61342985BC82 + F2D4674BCA9BAA83B26472B79FF707C52CE9AAAD55F31785B6D590E2EE0646AB + B94DB2913E45AB472AEF9F9A512BF90FABFC5D51B8F485E8780F4DF62EF049AB + 3A22C327982E69831CA2CEEAB11724A0E66ACF3BAE4C86A300DA4D0DBF65DFFA + AC0EFFE6AAF87EFADB821BF85EAFFF75CBAE4F7CB86865FD976B87ECBB285015 + 9EB64FA8D3144765FC7D793BBAD4D6EF1041CAC88710F12FE36823BCDEA0CEA1 + 2F67B6EFBEBE02522D9C8C5B32081CD5BD20FA21679EA6620935F725D767AC40 + DBDC620980EF7A24E517E7D81D9EEA498F18C28433D85C3CE1079B45711481AF + A3B100BAD167D1C6426B8E4445F130A0280E3F52CFBF55FC1FEDE67B8D53D078 + 17A88426D097950F7861B958A853C0EB0BCF0B808E7E8D66ADD9606AF9480E04 + 88C7300AF09C448629B95D6F760505F367ABC8D333CAF8BE8E7E0473E61BFC6E + 951DA252C8A53712702512839ADABF9ED8A6DAC94F641030351D742549818E0A + F72CDC9CF4946C65EA554CCE4766D09A8D19CE974B01AD1258F6112D48877B60 + 003446AE5841699F5B218088977A88A324C0A62ED7513F406508418498E7C264 + 31B3F75D460F8F546D860901FDE299734FB4229A86D3E071ACCB74248E16FF49 + 417DF0F8807230B7E49F5C74D7BC177A933C1A44BD106EB2663BFDBA91AC2502 + 17D08968803DB6236F2A470E496F4425A3A1A8653E5EDA1C4B0ABF73B5751A9C + 97B92A882F910993C40E93CC1B494BEE3D062B937B881D001F063F1B8A2AAD74 + FFC4F72FD643A7D0105B9C7B33D2D51B87A6595838A6EF88796EE5DEB5D3D1BA + 9BEE3FAA0ECDFA6FBF38696D181D673F0464DDE52B0DFAFE3D6685DA63F64111 + 6584B7467C0465CBB4C9757B06B852F0257F1E7FA1C9776B06AE5AF89DC49A57 + 6D8649CE7BE80631C70A40389C10AF4D4BCECF2A4F63EB1CDE1320FE6123FA23 + D200141ACAFBFB11C259EE102B07FAD7912915EB5BB6E5CEF8E9695DEDD8747F + 0D4B7A130B47B47197F7465F100A9CADB9F8EEC1AD9F0EF5A50BAC6DA640095B + 43A4C64DCB162AB2652B3F498EDB17F1D7C2F04EDB355950D098FC32845950D6 + 700B66B45E86BE94A9246D334F189453B1EF739A989B4391EF58F8EBEA7B55C6 + 936389F42D0B33EB8E93A9DE3BD5902C69777CEFD00B8A8185F97A2373C01062 + 7278210C4360463626855A00D253AF097B39C1BFEAAB446713924F5213076488 + 3EE6A5DCF9BDE6247BC08BC9C79053B669DE22705C32572F3CC8C866D87221EA + 07D88B328E424C28F98C86ECA30E7D18F686D6A546054F64858E514BABB1D019 + E5705913BF98E82C43ADF95362A9F1ED2797B0137F86ACEB70285CCD957A932C + C56F815F2A1D7A5479C1AABCFB5D343B645140786EBE2D124BF269405EE14EA7 + CFA8D3E68F51A860B4494C1F3F4BAA925782A620484EF3657725DA82B8D31698 + DDCD9277C1EB34DBB07E38DDF98F93D90730ABEDC890D59639E6286A0B010824 + 1AB71F8C69F3ACD2011B0704102E87A3E82CAEE2109C61464747CE44A7EAA17E + 7DA0DEF74189E812A52714153A956EF8A884E96C02E9FDA1BF563195AE2C2EB5 + 0AE4FE0EC56DFB7BA741644684766464C6071FC05DC8B02D228F0526C6C9F8DF + F3D5D3E8F44A9063AFCBCA5C7066834284B559E846E0B6412AFE8EE5AD37000C + 56ADC2931B8D7216BA1CEDC0421220135F7AEA3EFA11936B4E416D2716981F68 + 3BFE9ED8C4083AAE1CC84873F13524FA29E7F6317D0630C9E94A57E50A624BC1 + AD2F708FF94933AB4F684BD22864188617E9775039980695F4AC07E0F03B7037 + E2FD7A4490A6895E033690FA20B9631211DEFB77DAD7D1AD6343CF375178D5FF + 6C6005387B3C236A885FD9A3CDDBDA45283E4898484C86CBCE462C4602598757 + CDCF504E2BC0AB52EA1A90BFF791CA5C7F8C1A414CDE117AEA71125DA9A3C043 + 40424E1C41AED89AF7E352AD5D35D07218E07AEF99311D3F0DE40818B71A2AEC + C5DD84480C65BA82A22C8D45D622B06A37B591890CEEC54B2CD20B066DB0EFEC + FF744007999AC933A1CA46B300B18DC1A8A5E18C44D18165460C61617D45959F + 1E01018F67CC990C1806D6EB3ABB4EA1CC68314490D9DC1C87F4B7F755F1C5CD + 7E6DD0A34EE3C8D93CC34CD6399B35D73AEC811AF61A7BBB0E4D453C693F4AE1 + B262DF324C144E7081CF5907C8ADE36CA74BA94D083AD3494A286581C10D39C1 + 2D08A713EA96A579E8AB1C0E0217A2F0B2B466A272A882712126ED607DB50D6E + CEDE1B6E7A0B792A4652EFED3276B0A3FD2175D2B047E7C44F3029313991DF82 + 386BA2DCB26587145DB5AB6B9EE41ECF68EE3556D5D3478F5D2A863D234F651D + C734AAFB9B443FFA05717B87C12541A4936A49334C5E9AEEE2AE343E58C18063 + 72A7D01056FA5C6D8AC427B20C5CA10553E458AB70F2597B72F8573D836C217F + D615D07845228F83F1CBC2CB + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + cleartomark + %%EndFont + %%BeginFont: CMR5 + %!PS-AdobeFont-1.1: CMR5 1.00B + %%CreationDate: 1992 Feb 19 19:55:02 + % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. + 11 dict begin + /FontInfo 7 dict dup begin + /version (1.00B) readonly def + /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def + /FullName (CMR5) readonly def + /FamilyName (Computer Modern) readonly def + /Weight (Medium) readonly def + /ItalicAngle 0 def + /isFixedPitch false def + end readonly def + /FontName /CMR5 def + /PaintType 0 def + /FontType 1 def + /FontMatrix [0.001 0 0 0.001 0 0] readonly def + /Encoding 256 array + 0 1 255 {1 index exch /.notdef put} for + dup 48 /zero put + dup 49 /one put + dup 50 /two put + readonly def + /FontBBox{-341 -250 1304 965}readonly def + /UniqueID 5000788 def + currentdict end + currentfile eexec + D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 + 016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 + 9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F + D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 + 469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 + 2BDBF16FBC7512FAA308A093FE5CF7158F1163BC1F3352E22A1452E73FECA8A4 + 87100FB1FFC4C8AF409B2067537220E605DA0852CA49839E1386AF9D7A1A455F + D1F017CE45884D76EF2CB9BC5821FD25365DDEA1F9B0FF4CFF25B8E64D0747A3 + 7CAD14E0DBA3E3CA95F10F24B7D5D75451845F1FB7221D7794A860756CFBB3E7 + 704A52A22448C34812C3DBEDD41892577AABA7D555E9298C1A0F7DA638078167 + F56E29672683C51CF1C003764A8E7AD9D8ADE77B4983F56FE2D12723AAD8BF36 + 682CFBB71B1D12210144D39DD841A971F71DB82AC6CD815987CDCF29ABC3CC96 + 5EEBD5D661F452C6E0C74F9ED8D0C5B3755551A172E0FE31EA02344176E32666 + 14B6853A1C303A5E818C2E455A6CF8FC9A66DC6E279101D61C523BD9DB8EB82F + EAF4D7FDF6372383C0794C4568D079648689A199D4B65BA646CF95B7647E4BEC + 83856C27A8EF177B3A686EDA6354FE9573E123C12EC4BA56A7E8BFB8F9B75147 + 9DD79A743968F36F7D0D479FA610F0816E6267E5CE327686A5485AB72201525C + FB3B7CA10E1BF26E44C24E1696CB089CB0055BD692C89B237CF269F77A31DC81 + 0F4B75C8400ABCFDCEC6443CD0E81871CD71AA3064ABDE882C4C52322C27FA8B + 41C689F827FB0F8AAF8022CF3C1F41C0B45601190C1328831857CBF9B1E7D1AA + 246117E56D6B7938488055F4E63E2A1C8D57C17D213729C68349FEC2C3466F41 + 171E00413D39DF1F67BC15912F30775AFDF7FB3312587E20A68CF77AD3906040 + 842D63C45E19278622DD228C18ABDD024DD9613CDC0B109095DB0ADC3A3C0CB5 + AB597D490189EA81239E39202CBC7A829EB9B313A8F962F7879D374ADF529BD0 + 5533EF977142F647AD2F5975BA7E340419116099B19ACCCC37C551226DB28A2A + 49F6394324396BF03FEDC34E47427C7B14B81F600732AA1A19FB0A52B6E80FA5 + C5281CFA8ADEE3DEECBEFA91BE8A455A4B93364E087A8EDA1EAA0E0E14B621B7 + BDBC9CF2476E4DF79FFE7967F12B36403F63B3E9C5D00653975872642043D77F + F178369F138268DD61AFA06EAE4CFED07CF966122596816385AFDC28836247E3 + C3F5757E7608292182CFAD5510BE507FB1F760369A2A9D8DD89321B045B89C38 + 739A1B860E40DAFBB62DA7CA0BD0AED0BB12AF77B8DEC9ABDA40C1712672F3BE + 43AF20E1BB228A0AF7CEFB850AD9E4BF4EC373BDF89737C826F92A2FD09DC597 + 0504D1D0995C22FA958EE2AF7B3DA314F2DB067139AA03392CC74B983A578AD6 + 0772F1523F22957CD61FE32FA411F8058CE4A7761048D44FA9DCA5FE9282E480 + 73B8475E07C262FF6E869D40E6166F56F5926CB375064A581A8C9C7B348A907B + 0B781FA90718C352B08F20A56C4C3035DFF64D111E1242CF54C2585141CE23EC + 92F96E7274A24BD53F700B1D4DD1EAF2531D33A28B524C03CAC60C9FF966C7E2 + 340719D287EEFB19BAD2D2C9061C74AF6E8E9BEDA9D0EB615FEFA0D1DBD2D772 + DE6740409F4B947603305CE2CEC7C5A31C2D0EDB2BA4B91460E08C4B8B78D3A1 + B6C46D81620CD32F1B780532ADBBD9BE97DBC21160165907E2BEAF1693810F13 + 08BCD17CF9D4965EB57FFEBFD96E5F3CE21A8BE43A3B1127DDCBF04669B64029 + E9C127D2E9A6566F46BAC76408F9770A9DA2CD6DBE10F3D014D2B741BC7ABCFA + 9664ED5385088283F01FC2F5 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + cleartomark + %%EndFont + %%BeginFont: CMSY5 + %!PS-AdobeFont-1.1: CMSY5 1.0 + %%CreationDate: 1991 Aug 15 07:21:16 + % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. + 11 dict begin + /FontInfo 7 dict dup begin + /version (1.0) readonly def + /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def + /FullName (CMSY5) readonly def + /FamilyName (Computer Modern) readonly def + /Weight (Medium) readonly def + /ItalicAngle -14.035 def + /isFixedPitch false def + end readonly def + /FontName /CMSY5 def + /PaintType 0 def + /FontType 1 def + /FontMatrix [0.001 0 0 0.001 0 0] readonly def + /Encoding 256 array + 0 1 255 {1 index exch /.notdef put} for + dup 48 /prime put + readonly def + /FontBBox{21 -944 1448 791}readonly def + /UniqueID 5000815 def + currentdict end + currentfile eexec + D9D66F633B846A97B686A97E45A3D0AA052F09F9C8ADE9D907C058B87E9B6964 + 7D53359E51216774A4EAA1E2B58EC3176BD1184A633B951372B4198D4E8C5EF4 + A213ACB58AA0A658908035BF2ED8531779838A960DFE2B27EA49C37156989C85 + E21B3ABF72E39A89232CD9F4237FC80C9E64E8425AA3BEF7DED60B122A52922A + 221A37D9A807DD01161779DDE7D5FC1B2109839E5B52DFBAF552B11EFFB6A16C + F03FB920C15AE724EFDF0CCBF00A838D34440FF9FED532F44036AD22561184C5 + 283722DDFA7285E62754372D716D704AC0E00B2F6AB67154241C7449AA047833 + 94CEDB08E8C92907FE72A0B05AE36A7B9226ACD6E7890A0B528FDDE84A950FC6 + 801DE75CF2E739E9121149CCB8B1C87A106822648D84A3D3FBF295EE6C4BF403 + BBE9A1C1F6DAEDD1E642ACC486E609703D7612BFFD10C324F5DC710811F7F614 + 3691B400E3773987424C0D2B0D8A736873C6371DDB2442F05E018A2B5CA9A4AA + 17AABB95D09E5890CFFFED5AC01495D89A53D3C89F3D8DBAC85E06561646557A + B16BAE67D1DEF37B876183D3518306F16FC9A96C8AFDA5579A7CC82ED0CE58E3 + 574A85B0F37DF7414BB17DD5439734ECFF6CFACEBC4BADBB74A40726355F1C54 + 16122BDAE845AD3C8209525459A48B864C38B7F2DDB7B4BF3051E085C3E9B491 + 31E2893FE7871618F7DDF0A7165BD2DD4A0C05BD33D9E644ED7C50E444540755 + C06455A14646AD52995A3F9A74B44EAF2EDFA08D22FD564184381000D722A9AC + 886069C5755B1623B32E074423164D0CDB91E323970D42F3A3E059CF684D7F6F + 99CDBC03FD1EED3678B231093C986DC40FEBC47DF0828C6CF7F61ED6 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + cleartomark + %%EndFont + %%BeginFont: CMTT8 + %!PS-AdobeFont-1.1: CMTT8 1.0 + %%CreationDate: 1991 Aug 20 16:46:05 + % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. + 11 dict begin + /FontInfo 7 dict dup begin + /version (1.0) readonly def + /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def + /FullName (CMTT8) readonly def + /FamilyName (Computer Modern) readonly def + /Weight (Medium) readonly def + /ItalicAngle 0 def + /isFixedPitch true def + end readonly def + /FontName /CMTT8 def + /PaintType 0 def + /FontType 1 def + /FontMatrix [0.001 0 0 0.001 0 0] readonly def + /Encoding 256 array + 0 1 255 {1 index exch /.notdef put} for + dup 38 /ampersand put + dup 40 /parenleft put + dup 41 /parenright put + dup 42 /asterisk put + dup 44 /comma put + dup 45 /hyphen put + dup 46 /period put + dup 51 /three put + dup 61 /equal put + dup 62 /greater put + dup 71 /G put + dup 76 /L put + dup 84 /T put + dup 88 /X put + dup 89 /Y put + dup 90 /Z put + dup 91 /bracketleft put + dup 93 /bracketright put + dup 97 /a put + dup 98 /b put + dup 99 /c put + dup 100 /d put + dup 101 /e put + dup 103 /g put + dup 105 /i put + dup 108 /l put + dup 109 /m put + dup 110 /n put + dup 111 /o put + dup 112 /p put + dup 114 /r put + dup 115 /s put + dup 116 /t put + dup 117 /u put + dup 118 /v put + dup 120 /x put + dup 121 /y put + dup 122 /z put + readonly def + /FontBBox{-5 -232 545 699}readonly def + /UniqueID 5000830 def + currentdict end + currentfile eexec + D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 + 016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 + 9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F + D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 + 469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 + 2BDBF16FBC7512FAA308A093FE5F0187316F83DDE3E2D27FCDF6C5CE4F95B6EE + 3317BD91B7921F3039DD35FEA387D5CFB6C6E9DC84C178F3432994FC7FAC6E5A + ED41A1E2EBA350178FBFEB45944511731BA827167DDAC238FC69A5486B995477 + C469E2E27493B0B711DF8E267D3D5613B450011921685147114106C9472580BD + F531022F6DF5432B2A4EBC51A8032C7F9689B6FA942D849B29709631613DA68D + 4DF7B6F059A19304F40A3C3580CE3B51D79D42984194D4F178801720892FB6E7 + 61FF43C63F9256B5E9F4227B1378222BAAD4D52C77462DF01892220E11129C16 + 6C9E45BB9F01ED7C1AD5D8B4D72BE0E12969AFEA90FEF170603CDB91CB243173 + B19A56084D10293B80A35275F41BF78A054DDC98F4A1FFF592463D944960FB31 + 6BE5F03960F9B1F213CBCC7FD448657FE388F10104D42B0715FC9571CC60CF23 + C72560CBB8835A0CA208FE06676B3B48B093CB7FB2C0C53AF17EC5B372A9771B + BFD52FFB7062B4FE0106A01A2A1A1DD4EF5C8C7623EC9324A2CB3B402FCC1FCE + 52BFC8662F8A39D5F1B41C97E7CE34E16AC28A1E94007AEA7D4C519399F1B7A9 + 48FA7DDB671067244F09C29F95DD60668223F45BBDA8B1C452E930A9F3F341C5 + 351D59EA87462FFB30277D3B24E2104D4AAB873BB2B16DA5B23BEE25BE2C8128 + C4CF2F4F438A4E520CD932BAC455BF8775C27AEA6C73EED3EB2F8DB5E356AE27 + 41B35C8AEFE73C4CD6A591AAE4F45762EBD6D3636C03F08C552BBFD0A13D11D5 + 491F8369B4BAB8ED9D6F1DE7DB7AFD383986C4338D3AA71C9AF2B8A0955CFD86 + 0345F16D9798B25156DDF826A7CB6A0CC4CB43078BEBD3E499DA95562A08EED9 + 7CA27B7A0CE3FA7EBDAA87A600F027392ED9130AE06AC9A1FD8F9C8DDBCF2121 + D29351AB18D95CDF12F292C607372135DDE3F2A21E64F7261FACAB9AC2CAF438 + E34C25E3BCFF2562A725C869A8EF84D26D86DFA33DE2C9907926AC12EBA9F951 + EB43C5DAF2821E08050781163CCA0A39155A71E52D83C2C8F00536D377D5F62C + 05DCC078F14FF56E63C1BC571762F10A88C2DC3E2E76E496D3895EB735055EEF + 7C8DB15B09BF409EFB8FB66BCC8644DBF9FD7C22DBAC46C7DE15782C08C8D7A9 + 7C01582DD5CEE8B9ECD7F9C6CA0AFB492DA6DB7375807A62EA48F3897E111A18 + 163D509FEEB48253E8FD12C7DB4B17154FCC8A08B4DFD07E253C4A144AD5042E + BA0B356B033C12A0DF522AF0541C9817C432CDFF5891AD056BC52DF2F36D471C + E8998AE1632EBB9C23BED8DCC7CA75B4E73BBF65452148EFE0687EC80B1648A7 + 53E74C51C3A8C5AA32DA56C7C7AF9F8C33EAF5E2B34762909DC011B45FBDE02A + DF90B39B4519F1F9BDC7DB8147DCE406EC17B9F35FA814E9421C2792F2DD475B + ABDFF71F4CC43F64503305BA58C67A9FF8377BDA1A04D230564D103C7788700B + ED97ED9D57F3EB5F74B4225DF54CF205688DA8A086A2F47EFC9AF24D3C34920B + C818AC6184D44C4B8B316FE1B9C5B0BE4BFC742C2420D52D61AB4234FFFA7A03 + 1A5653EAB1A2BB6596D1CA7E8B527AB4062821645F5E7D395E1C259E5526A50A + 387D5CF6FB3231B6491D4796E277528553BE234EFA1A4C127FF9DF49DC811FFB + C5B49FC9387B53E63A6A67E37794E7926B3FCFB34AF44D733AAA8EC7A30D66F1 + 305FE4117A3EDB0B4B46FEA3DD1B3E8FF468E7998E0D0EEC664ECCD97A07B53B + E714F94E167363435F9617322FFE52060B8C35BBECEE59E4FA056F866FF52157 + AD730327FDF6E75553CECFCDB74BC9021ED9FAC4CE3475CA3A0391C81FA4DB3B + 4266201FAA4C16A652528DC3D8DC94DD9C8401C6EBD68F35C5683C950ED4BF8C + 4148A0224F2C585C8075B9A1AD63A63E2CE9B250877561A18DB70F5EE165E73C + 9D6B3D4E205278A71E52F1ACA4A5849C2591344D5539C529080ABB57FB1B52A6 + D89AB0C4304D4D2A737E6564E00EDB57F24C8E272317FC65FCDE309333F9F722 + DC5252F2449C809964E45CADEC2391C4FA8789F9DB6E2EA83A943B94B93A4CFF + 298AEDC6A8EDAF8091492D6F62B6832CA110F7345A5D08ECA1027AEC83C3F05D + A450785DB29F28129644969BC40C62C38452663D0D74B9F6CF3DE540BC3DCF7F + F92122B8BBC36BF742CED844CB73412DE8DFAA19674596A00C060A4FF41E69A8 + 67513DE42E5298688E0CCE44677B8E37706457A7F3C4E11CD404FF50C171E693 + 959FA307DB2E7732EDADC70063229C26AA87A3D832B12DDE696444A08C1BE8D3 + 30B1F87A257E1839FF918935E13641B138BA8667FD1DA91239C6D879F932E9AF + 06771B5CE3846D675037101A689145702A1EB9D453DD84330EDB29A5C70331BB + 54CF36851E12C84B808BB8AF4C5F7CA4243397962008FE5CA0B54D164D839A9F + EF58C56C7C464DEB315FC2FEF912D1013DE1ECFAA33D332E27D93D826712D5C1 + 6C92FF3E380324D012E088BBC363C61E3247C157B4FFFDD3C851623501B35C3A + F650DA55A881DB882761F7557F807CE51BB0F551FBAD4AB0745ABE6E5E0E6233 + 43E508EC9A2084F40D203FE46CEBAC05CDB94EE44ED0F73276E47328877607C9 + 7A29886DF48C32CA82E0F53559BF9DBE08FE2C7798A9A147B7F12FE98A803F9C + 7160C44F7F55AB44E50D58577B8D3088817918C6D6DFD3A0404904F6CBAAD650 + B0AFC753CC86F58A94C375420500D967D926208BBB2EEA9256E825459846BEE7 + 226A84BECD147BB4AE8C1679676C08E30B0100511E4E66DCB23EA8D6CB7033D6 + 4ED45FE150FE715040C432B2588C2E590B17A3F598EEF370EFB7F8E02B5F6A04 + D537B6D2645FEB59FB53C6F1C760395ED787201C891EBE7F735375DACD624789 + 9036FB8763DC0B17E112516142664EFFF3AEB6B7EEFE8466F79E4FD851632283 + 6BF25A817198682CE8930EDA0E84FBD089C462BCEE865863D20B2D46D14D709E + 181DD0E127C8CD5820F1C31528418A8F1E9551D3CECB1156CD693AD6D567770F + AB10E608B7BA20EABA55CB2D10642F4A06593DBE519DD3CC3FB9CBC565134C91 + 1BDF321B164486CFD35D713D839184A8EB996C35C54043D2C4CC8FB3E6C5627B + C57C83E3C0E9EEE3E75FA0008F6B8171BBD2B8A1456403F17D2C255AB9C88C62 + B2FB74666EC3941A824DE7D154229372205A55A24AD8B5E3AFEBC94874C07D8A + 14FF2A0587ADA5BAFAEE4441DDB11ACF3724AB0C4B4EA820E693F846A467D2E7 + E4CC84EEA26F7F793C8F252C3FC30E42C178FAF549918596A9EE31094FE3D2B1 + 70E92D5F458DE15FB2C4EE7D63677B0D3701FFE582D65D483B449939D3404A47 + 6549FEEC188BC5FEF9070DC99248116DB78FBC3CBED435DC2956B5C3977211E0 + 53E912E4EB8AFDFF29C543DA483E3893E9C7DD9A7C61D2F7874112C1913BC703 + 3F5AA48B228C930929B739A04190B661D134674A546C840A362CA22C6BA36AD7 + 73BB9CBA9DA8563EE289589BECD0D8C7525801A6D504830CD49ED5797A5B85B6 + C722E0DA4E01478F86B7EFF961130C4B89FBD11B368816361EE64B8321298028 + 62DB439443756E8B7CE5208FAA01C435BAD262C7C7D93A4467C17E49A75AEE66 + C7A5E1397EF2E4DAB16AB0516793234D439060707A6924577AD8C7B087BF6864 + 02737A2267A54BC39E4E76A5DEEFF2079F46A7D61D1E1CA5E5B13E575E3BE1FD + 8472D3543D05D2FBFAA2FC13CDB121E171BD60231E677FDECA5CDF969DE6475B + D910090BE14E3F7CF4A270D8A4B3E6804BDF23290059C952F81058F496941222 + A6B168C8C9EBDCE32616E38AB0DA70D0265929B1D35E347D1860415E2C14ED25 + 363DA2A6F81CD2380D37FCD898F926BEE06D1674342741353CBB7CEB248F1768 + 965B027628EF67DC09BB2FD3C0A71D2F9FB5CCDF5301907DB67D16EA911509AD + 78BA6ED12FE06BE6BB79CC1EA949149DC34A6A1802429B8ABEA27C711DE37E48 + AB66DBAD9C1036251ED0CDB9868D68125FDD4337DA34883985EF1A827F126460 + D23419EA59F3A06D66FC8219AE19780EFEADBE1F4988C22381FD8FDB9759687D + 9F2CA5F6D372F9D9C7850CC8309D8802F29ABB87E803D6A1D7AA038F79322794 + ED2B01A7FDCDFCA0900D533FA43571861DBE0F7FFB73507FA5A32ED1A59144BC + 3A9BFF6E8D7E9C3CFE185E257C34964D944E069CEAEFC54738A9FD2B63A6567C + 513838FEB8CE43E05BFA7E6DA3E4BCA78F20296E30BC066F16A8A10102668664 + D145A6D9F710CAB6D2F1F0565463A568B2988097668B983E1B39326EAC0CFA43 + 2943E5595DEBA9CF3BE8F894AA0227828DC76166853D19F320E92E173C6D763D + 2AA589BC99B435F607FE20E780F3434CF5DFD1905E5DAFA131A74A9C4BCEF2E0 + CC1A1562A7746B1219E37B35A923F07290C642F8E5BCBF2C46BD61036656AFA2 + 7E20B77CD9EEDBBA01AADDB6F71745445E23DD5C32113B3C78B32EBEB1EBFFFC + FA91749578899A878854657C00E07069FD31182C01F6246659DFACB66E924A01 + 691663AF90F08BB14F0FFCD30810B2C02988CDB0361DC94E486FD7EEBCC1F848 + B15EB1D908F5C5DF62C78FCA2741D13F599092663FF4368A0555AE3BAC779B20 + 1AA96C01FE9F10AEFA7E1C3BF4235811DDF27A70E0E07051E45C3808DB3E0DF9 + 36B68C398592034C98866E4BEEE585D031454FFF21694C8CB5FA681BF1D56065 + 397417AA1B58B30244B4028F13E60CAF7FB4ECD60EDFD27E509E90FC01F4D165 + 0ADF0BB5F3F4D0F8CA923D4B2F5A9167F641EB6AED279FE1D931ECBD437C25D7 + B729B45732C6388378C1668D125AFBD4C146A5FD3FD621FC4407E20BB51EDA6C + 3C4A763F2AB4A6996571E38FA7074672B9BD29D1499F7E2E1876804E242750CD + 7191D34A517175CA509953FD397CA4D58B46E9172071A4B39F70F2B11AD71CCB + 2722F498E8121771B9B9E29F6D67B2C6F8B5AB7F3B1CAE55DF38CEDA75BE5886 + 273E18BAC67F4C38BAE40E581AAAA016B6392FF1AF91649088D1203B1011A8A8 + 6E016216A45583C8EE14B5790442A647928DEC6079F12867F9150DD20896F8D5 + BE847DA1D653DA52754617479610F373699A9C12DC403A56EED961F4046CC9D5 + 001C5AF2E46D97F022AE390B7CECE4CC2B6A445BA09BBD7BF09FB200A1C84007 + 9A63EE918058D39A65BE87C15BE8E24C054309C71326065CA9A4A00003169998 + C520D7277DB119E09C6393CF43F4A81F74C5C347B57885DBDA12B9E034B7FC45 + 127B31ECFDB67107CCDC73E2E7F4986B7B3CB1C6BEB949658C590B89A2C11963 + EBB464FC702C5DD430F54B51A66F477221BC434B5DB0731DD2F0A610DA18AE13 + 52B57BE3AAF6DE6EFEBBDA9C15410103723DE220D8E9DDBA8CC7E7F59EDA01A8 + 87E39D7AF5D15259B38C8EB0AD0790F6B59BF5992DD7034BB46928FF757D8129 + 6197C1A24C6120F22842ECDFE8F4E82F46B6A13CE986D43254287239334E27EA + 1D61012D8B002B01D370E1D6EC75BE5DC0502345660E7367A4D914BD03F88029 + B8F165C3754BAB39995B25751098A17B7562AEA221C46E4B4895055D7FCA348C + B83F307309CC1D947A18F1C64C82C14F1EE058F5757767D17B4598E08939CCA0 + 0C03F566A95305C22EC053A4BA95479041ACD7B8E0DC95601C304FDB3EA61DEB + 48E2299CC26E505F0B89AA51FE053B8ACD90E83EAB4ED798CFC1D3E3F3231B09 + 57F0AE89E7EFB03C1DE4D5E64F5B0AF2EA6074006BA0CE9A6EF751C82A98ECFC + B844C48675D015144A6268DA9D10FAF4EA06BF32A19C9985EF91CE163EC6DA97 + FE341512F072AD27ADB72007E5C6D795FC417F3AFD6F53C16CB40B3D6F60FCA2 + DD3D20B7C4F06D785A79B0383325E3BA764072351223BAA96E74659D9B2C5BFD + 1109CFEF6F1D741F43D866DD8196437DB82817E893DF61A5FCAC7592A0428C47 + B65C52294FBFFE4C954EDD6637EEF57B7A85D4C051A42F3B1927705FE77B197A + 693AC5E3059954D3820B530EECA9A48CD4D450D57C46CB6760BC01D1F573777D + 4E0395BFD1C0962884A037E42160642E48C1E0653481FDED22F46299744651EC + 803F9EAC6185A2A9D19E7B1A871EF347B3E70C25843C7FCAE1C2B00CA7967BCC + 777680142F5E35504FD93858EE6BB3E461EB15E04A5E912327C0175DC093B96C + 98387E7D07B2A706E7F626EB77EA624375FB35C9C82A035758AD62057B679B66 + B7EBDD7F50E486B6A9A4CA06486B96D371C02E6C9F4C738136ED05D02AD8BCA0 + A38238EC5A8823D81675A1736ECC8803A1B3AC25BC18C2A90039928BF2EED8C0 + 34368FECDD7727AA0115B7A6756B929362F3C9CAE3FF1EB06563940BE322CA3B + C38CABAE3B1977C5150D6AC4EFB5E30CCC3712822BDE50F5275B5EFB43C12CA5 + 94EB7B26D8C3D746B2569EE4276963A699A70EC8A705975580110358EDBFF41A + 4D1FAB0957862594284E240CB9ED84CA02995A1FAFDFFAC1D12D220E256FBC39 + ECB83DAF254EDE45612124B2AC153733811A0333ED6E77ABF2B30ED7539E1111 + 411E81786A728802E8D389D06076D59B42D758265E64E2E4796A2218FF56F5FF + 73F651CC930AEDEFBCC097547E5A3F42DB269E34A848874A38565E4BA87BF2B1 + EFADF2424B12C4D96CB81C4334AC07EE3BEEA8DD47FAB1D3B6AF327670733D1E + 4C985D5DDE5BDD00DCA91C9D68947F1FB41E3698B2128BD6D6FEE63281F8A489 + 25C249F80F0B535460EEA2EED470DB3686A169B23BA2705ADEC6E6E3B2003974 + 3ACA278D99C5B74C96D4A895A61A02114B152DD8CB055E3B9CA33D94527A65A8 + 8FBA040CA8D7FCFB3D9C221874F9270C87F48CB7FDBC9F7E5A62B16C4B2B31EE + 28947AE2AF096B8578F29B6C65A32EB65A1F2473C0AB042D2E1AC5E5B2403957 + 6EB6AFA70F76035D7D64453D74B64A1503589E6AE283B6459F0DA46E58B52E93 + 918AB5512133D05FAB92E8DF07DEDBC7F25A341FA32FB2389B1992A7667B2E43 + 39CE6F133D209298AD9AFA0B9BEB5037C6B827FFE05A3AFDDE18D834F87A11F3 + 5E5B9D9934F1475AEFC3DF1691C9F60FC29D36E115FB40533EBFBFFF9F6875DF + 0099B3CFB4BBCBA583EE51CE20D21B8D0F3295D7883E6C07270B4B943ACCCD65 + D19C87D26C71550FC24B73A6AD0F953662E49D87A8FEB0DA500DC41B3BEF95FB + BBFFA7FE7E876AE1239C290D812911334E5D3E69D33297024D30C0FEF2955453 + B3CCB84D967EE21D2E24C2C1D539CB4EB10CA7BCE9EEEEC7DD60326216E22908 + 9367A5AE2141D35009E015E1A016B1750AD821293D8FDCCE481E2AA605C953C1 + 26F47EB1C3BF0FD8C42A97E4C5E4433AC4A46ABCA50047EA6DF0D2AA561EFEC3 + 6D06C1300E61FD7ACA5439FF63BC863396269F9F106D85BB8C50876057D316CC + AA6AC3007227A5F52A9994B6E5308BEF8BCF251CC36AB408A27D6B1D8FC64087 + AE59B11B7A572682AAC3CFA072F2BC3B716FFCC09C754D6E21FFC9A0909F838D + AA1BAA2C25690F9270F608754A2DADB5DEFFCC3A06284ECF0F0C83F6485ADF3A + 8EB53AE3F4CB156E7E2C7ADD297B103CAFC4C604DE489893F89346E8E615D304 + 709DEC558C23EDA06951A56CF4EC60847D63744F03CF2680553554EF7F3C8258 + 7E5EF8E0B840E8EDAE794C503EE2B381CA4388BB74AF76943DDE2146F4774381 + 75DC6F67FB48659546720294D6C1805DC7BCE7CB7EC65730E43151DC705E8A98 + 8023F258C4C94FF86AE3B253E062ECED5A14C2FDC0263DB779B36B82B2B1D7E2 + 8C1AC2364F2738D2BC8E794CA04F99E603052DE0FBBC30229E876A6D705ECA39 + FD6E53CD71B9DB4AA7333D99D95C3D2EBBB515FC9DD07A3F30ACA33312080460 + 1AFB4972EE9ACC91821E47389A7D21DF18A52FAADD39AB45B16892B1B5EB1209 + 8573D87F0B11081945302A05B80C8D075E485BD8975B8FBD077A9194C199D78A + C7F6B29310C035039ABA551B9BBB12329BBC6E1ED58DAC6B2D250CCE7F64E8D1 + ED72DD62E6BE765902F6FB712BCB9AC5EB1243B409E8EDF99AF3E5D3D3FC87D4 + DD710A10D1397ACA02468C8A87FA0A89A35A82EEB478BBC3E25B7C0E2FF5377C + 7FAC70FE86601A716C765DE378DB752DB7E9522890DD6926E27D01E8532D0413 + 4C8A2D2E0D3EDFAB032ADA00413C0DAB8BCAFA5589420452BBB9055DBED26B3B + F885ADAD2EF2E928636BFF4FEA4D18EDE8706A729C906E97AD3584FE87B12A01 + EAD3538C5AC751F9FDDA5E4C385963409D680B515B2BFACBEEE2DDEA34450007 + 75313BAB84AF747E049A3B1317C5CDDAA01F9F56C28877E0056DA036B07CB267 + 6ABFA85FF2B1E623D406B3ECD548C2C5B51DC6750593E139AC72C66F55D6E319 + C5D934CD0C72A75FE4E39ED5AF07735D9DEB4930EB1790C6DFB22F8CEE10D4BE + C79F9BCCEF98E6134BC3BB9AEEB08130324BF3952F25EF32A1E41406F468D41C + 0794B007913778A1DB9781F4849CE15C550D892AEE45950695B9E17EAE76C873 + D8F88C68E620CD950DA953547921592C57A23DFE434620C0D6C7E230384968FD + 853EDF0B0830B0B3D4D3377DE77EB19CB674C4EA97B8049AEE9C2E57FE36707A + B6017DE314994B2739B1BFE1223EB1E8BCF02BCD96E3F958AF368DAA0352FF14 + 49FD0E17DE0BB4E549E1146F05D857DFCF5507DDBE4DD6A375C8E260961D9A42 + 5E36C9A539F76080601FA203AE5B32CA7EA57683BAF571A2342DB35E788D8EDA + 54D8DB5B74F71D7EABBD4F1061A9AB8219F907D13A33BC0660D35F43F0472890 + 948A4EDB07081DEDAD8ED5C1B0A6E8AFE4759E89BB70AC8D42F62A34C6191859 + 7BCD7C993BFD3FB3CFC14D4D45E45CF597047198F0175DCADE5DF15A1D3A2F50 + 550F + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + cleartomark + %%EndFont + %%BeginFont: CMMI6 + %!PS-AdobeFont-1.1: CMMI6 1.100 + %%CreationDate: 1996 Jul 23 07:53:52 + % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. + 11 dict begin + /FontInfo 7 dict dup begin + /version (1.100) readonly def + /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def + /FullName (CMMI6) readonly def + /FamilyName (Computer Modern) readonly def + /Weight (Medium) readonly def + /ItalicAngle -14.04 def + /isFixedPitch false def + end readonly def + /FontName /CMMI6 def + /PaintType 0 def + /FontType 1 def + /FontMatrix [0.001 0 0 0.001 0 0] readonly def + /Encoding 256 array + 0 1 255 {1 index exch /.notdef put} for + dup 86 /V put + dup 100 /d put + dup 105 /i put + dup 107 /k put + dup 110 /n put + dup 115 /s put + readonly def + /FontBBox{11 -250 1241 750}readonly def + /UniqueID 5087381 def + currentdict end + currentfile eexec + D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE + 3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B + 532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 + B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B + 986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE + D919C2DDD26BDC0D99398B9F4D03D6A8F05B47AF95EF28A9C561DBDC98C47CF5 + 5250011D19E9366EB6FD153D3A100CAA6212E3D5D93990737F8D326D347B7EDC + 4391C9DF440285B8FC159D0E98D4258FC57892DDF0342CA1080743A076089583 + 6AD6FB2DC4C13F077F17789476E48402796E685107AF60A63FB0DE0266D55CF1 + 8D0AD65B9342CB686E564758C96164FFA711B11C1CE8C726F3C7BB1044BBD283 + 9AA4675747DF61E130A55E297CA5F0182A3F12F9085AF2F503481071724077A9 + 387E27879A9649AD5F186F33500FAC8F7FA26634BDCE1221EC0ED0E359E5EA5E + 6166526FEB90C30D30099FBDC1BC2F9B62EFEEC48345160804AA98F8D0AA54B7 + A480E715426651865C8E444EDB798C7E11040AF6E5A7ED1888653C6DBF5E6169 + 70BCD9C063B63B561EF165BF3AF11F8E519F37C6FDA2827685739DE2C48B5ADE + EE84F067D704D4511DBFA49E166D543CFD9ECD7417055D8A827F51E087CD2927 + BAFC7E6CFBD70B0FE969F890A11149D3D44D422C3370495DA9951AEE7253A49F + 3A9444C8CD9158D84117299F7F2332FEB0F94E6ED8BC7AA789A3219BC2F227D3 + 3B5BC75FB53B55D72AF4A6A7BB613FA235B11BB37D059FD87127CEF73D5B3FBF + 9F91ABAD78BD9240BD9525EBA78095EA0BDB25D1A19E876F292882EAD5619D46 + D20317A345D931F4FF4EAE6216C27044CBA525E3B917CEA25A04C120466C4B93 + FC720E6BA832A06CCA0A3916CEF0968D49085AEBD243C41A448289A6F05CE3F5 + 79148DC112A3CC7E8FF810B8C1A09E05F496C0F1EBA334E42E05C376C98F5F69 + C06C71BFC0A2F3AC9951CFBB143C66FB84F9C4ED27DF70869352D61BD5E11508 + 0797B87C74D8E22C8581255E53BBF5A60D2A2093A425B87BED042D98511AC458 + 40263CA6C8EDC90809C5CFA64074ACBECA89FF5232C9D2A5CC330DC83E5EBE1B + FE64FE24C15123B7A19C909BF1B2E4EC48294BA721F84BEE62A4A4F85C397EC1 + 4384918D5CE9A024FB2BF7C3585452E5F916677264706828E1E8A448C2FB7DF8 + 636CFDE774416850E0343E96C3F1968BDC4AB3BCBD60A794392309CFCDF2F817 + F7750EF43714EC855DF81ED6A81E4B42B0416A40D29D81ED7C2AB3C436A94CEB + 243703538C59F94C9E289A2D7970F47BBBC6B73656A75F08456FB6408B696CF2 + 6AF5F9D1E076F6479D52D48F4CD93114CD572F11A3EF966BA5142B580C44C911 + F2D28CC2F297733FD55942C61B0051C7269B718ED6457045DBE9DADCF6C67993 + DF0EF5805C7AC3CDF1EBBFDFF5A9155690763FBE5C81AA74453ABB8200B676AF + B6662F8B9BEAF0FA7B0349C50A690E3ACA076AD20F1E533E6546E16059DA3AE2 + BB5056E4A19CFCEB32747E08048D6E0FC70B8501526D92A5E5FFD237EE00AD86 + 25FCBE1CDEF7227E5A5C13B309B91E0A1E7E8C150CA757F86CABA83912EEA0E7 + BE7119BF6F2232A31E9D7D00C09922B062C4196F56BC3920F5089E4CFC448DA9 + 62CBCB1691065694EDFD2A6C2D192C38157CADAD01A03574F7FE666E6C693B2B + 1AC5FEBE93571CA24261E00DDEE7F5249398209CC823000A9725D4CEE9EE12C3 + 9211D32A32176F34155A5B13EA381585381B47ED9EE16902DFB503C442FF9D6B + 1D9B27215A79FEEA88EE50B756417D91C5BC75F6A4684362234585662CDA26B3 + F7237ADE44908306D999F30437D5662B1D8A226D056EA1D9AD4E5B9943F44BE3 + A4313DCB90AA5664EEF2AC280C292CBF10F7AA2D56D7BF0A8737C35BD818E92B + D8E604701C560887502408FB85C068C796ECEC6BD09232291B853E04CE2DA712 + AF9E01BDB0857DFFAFAE0BEA292BDA5792425C93E331E5E8D9BEE11980D63032 + 2B4AF1914437BDD54D9F169D3BD6F0C685056ED58041C1299A84DBB50F924A78 + 70F12796D48BAF3BE90C8B7B46A17C218FEE7715185042FEDD8C483D71D05FA3 + F89EDD501091B5EB395A86E4CEB450B2169AC782524001F81DE9FBD5B0A1B8A3 + 07BBFF9C8E1997E606E513E3CDFC9DB79FE915C11D886DC13A8648BDB58EA982 + 761F7C42B98B7ED87066E3885533564A6D9E7EAF55725DD3F65446A5B030E5A0 + AD19C89A847E7398DF6429453B511D444CD55F57BADAE986C81DD272EBC15DD2 + E73D8293EE0BC84D942887BFD7400F664E0632AF180F365347E4160DDE094D8B + 8C841811EF5BBF248487FA756AC13A3F990E9827392DB7B1BF25E1D33E3158BD + 87BDBD9C62E323C54CAD34361A5711738D7D6B5A452034A6C8A1934B0FED228F + A793B4DB20C8875F24B94971A90B439E1F9966F5FC695301A1FD56B35C063BEF + 8CD0DD039B29A15BD7E1F1665DE0485BC75B3BB158ED58831DABFCDFB584B8C4 + 8C866AED0FFCCCE309F9F1BD7FE3851C176DFA8BA0EF8B496468A48518992537 + 0CC7FA8B1AA5B84BE954F4DCF985E9CBAE78CCEC4405B29B3D9862B1BABDBC6E + 62CD48D2CAB357B54ED4993E83C432D0C21D3F21FE1CE9FDD2E09C5DC83412FB + 699E6BA0D342DD27D82E53CAE2ED38ECCE583FD7790F34EC785063C8FE2503F4 + 12F57B9864C32C4879CBE6009A26026BEF008350DE6947FA8D70BE77417901C0 + 7EC070713B1A68B77CA7C8BD8878BE8D4E81021D5CFF0687F7F7DDF4AA8E5796 + 9C4B6BD1D26C0AF8F4838B39F1B5A73F77D49AEA1FE7EA47BD40C7CA5F3E1EAE + 3D5ED928786469472C2169D7C4EC472CEE5B337E12933A279D5D56FBB24252A6 + 692A692223BDB61BB7E647A9FC1833A5D797356902C577A8A980A04A505DD96B + E3B15D3BC19770AD9BDB3AC6E2CBADC3397D8B4CA314C5FAD22F61249CFB6BAA + B419763C8116292960D6E2900D2C27A72A781206283233FB7AEE3AF699240397 + 23B3B447F7A2D376CABDFC1259E4F0E0F79B3B451967CEB308D31216573AA603 + 60EC6F95813FFF0257BD695589B7FC40A1BC9F598CF2BA4F2024526B66162401 + 262A + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + cleartomark + %%EndFont + %%BeginFont: CMR8 + %!PS-AdobeFont-1.1: CMR8 1.0 + %%CreationDate: 1991 Aug 20 16:39:40 + % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. + 11 dict begin + /FontInfo 7 dict dup begin + /version (1.0) readonly def + /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def + /FullName (CMR8) readonly def + /FamilyName (Computer Modern) readonly def + /Weight (Medium) readonly def + /ItalicAngle 0 def + /isFixedPitch false def + end readonly def + /FontName /CMR8 def + /PaintType 0 def + /FontType 1 def + /FontMatrix [0.001 0 0 0.001 0 0] readonly def + /Encoding 256 array + 0 1 255 {1 index exch /.notdef put} for + dup 11 /ff put + dup 12 /fi put + dup 13 /fl put + dup 14 /ffi put + dup 39 /quoteright put + dup 40 /parenleft put + dup 41 /parenright put + dup 44 /comma put + dup 45 /hyphen put + dup 46 /period put + dup 48 /zero put + dup 49 /one put + dup 50 /two put + dup 51 /three put + dup 52 /four put + dup 53 /five put + dup 54 /six put + dup 55 /seven put + dup 56 /eight put + dup 57 /nine put + dup 58 /colon put + dup 63 /question put + dup 65 /A put + dup 66 /B put + dup 67 /C put + dup 68 /D put + dup 69 /E put + dup 70 /F put + dup 71 /G put + dup 72 /H put + dup 73 /I put + dup 74 /J put + dup 75 /K put + dup 76 /L put + dup 77 /M put + dup 78 /N put + dup 79 /O put + dup 80 /P put + dup 82 /R put + dup 83 /S put + dup 84 /T put + dup 85 /U put + dup 86 /V put + dup 87 /W put + dup 91 /bracketleft put + dup 93 /bracketright put + dup 97 /a put + dup 98 /b put + dup 99 /c put + dup 100 /d put + dup 101 /e put + dup 102 /f put + dup 103 /g put + dup 104 /h put + dup 105 /i put + dup 106 /j put + dup 107 /k put + dup 108 /l put + dup 109 /m put + dup 110 /n put + dup 111 /o put + dup 112 /p put + dup 113 /q put + dup 114 /r put + dup 115 /s put + dup 116 /t put + dup 117 /u put + dup 118 /v put + dup 119 /w put + dup 120 /x put + dup 121 /y put + dup 122 /z put + dup 123 /endash put + dup 127 /dieresis put + readonly def + /FontBBox{-36 -250 1070 750}readonly def + /UniqueID 5000791 def + currentdict end + currentfile eexec + D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 + 016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 + 9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F + D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 + 469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 + 2BDBF16FBC7512FAA308A093FE5CF4E9D2405B169CD5365D6ECED5D768D66D6C + 68618B8C482B341F8CA38E9BB9BAFCFAAD9C2F3FD033B62690986ED43D9C9361 + 3645B82392D5CAE11A7CB49D7E2E82DCD485CBA1772CE422BB1D7283AD675B65 + 48A7EA0069A883EC1DAA3E1F9ECE7586D6CF0A128CD557C7E5D7AA3EA97EBAD3 + 9619D1BFCF4A6D64768741EDEA0A5B0EFBBF347CDCBE2E03D756967A16B613DB + 0FC45FA2A3312E0C46A5FD0466AB097C58FFEEC40601B8395E52775D0AFCD7DB + 8AB317333110531E5C44A4CB4B5ACD571A1A60960B15E450948A5EEA14DD330F + EA209265DB8E1A1FC80DCD3860323FD26C113B041A88C88A21655878680A4466 + FA10403D24BB97152A49B842C180E4D258C9D48F21D057782D90623116830BA3 + 9902B3C5F2F2DD01433B0D7099C07DBDE268D0FFED5169BCD03D48B2F058AD62 + D8678C626DC7A3F352152C99BA963EF95F8AD11DB8B0D351210A17E4C2C55AD8 + 9EB64172935D3C20A398F3EEEEC31551966A7438EF3FEE422C6D4E05337620D5 + ACC7B52BED984BFAAD36EF9D20748B05D07BE4414A63975125D272FAD83F76E6 + 10FFF8363014BE526D580873C5A42B70FA911EC7B86905F13AFE55EB0273F582 + 83158793B8CC296B8DE1DCCF1250FD57CB0E035C7EDA3B0092ED940D37A05493 + 2EC54E09B984FCA4AB7D2EA182BCF1263AA244B07EC0EA912A2BCC6CA6105B29 + 044005DDBEAF88E0F05541BBD233977A447B469F013D8535A9D7023CC0FB7B49 + A95CD2B6F18935C37F49E9A73E97A8602C5C26EE13D7A04A188336FCAB4CDEE0 + 23DE9D803FD6E8D846B3F729BD36137E834E016242CD2F7BF048959DD45AD413 + 19B985D05E5D422F3D0968375EA6A90FBEBF8B42B15F15280469D69629C08A42 + 1C298CC027CC288B9C984239ABB96B6A891C1360D08F9ECC22202861E4CE9B39 + 8BF329F41505801E80D44192B4267A538C9DB82EE98E17CAEC068F7B2B750260 + E2B4A6DFD9677D28F69346AB75EE1EA754DE12D5CA0286E55839EA9A46D9109D + 56F8B230A446C3162EC8503A085D5594006D17AD56E5BC2FB04910450B0A463E + 6CCD91C5C9600354F01023F9577F2B3EA74E9C7E64F44294474FF49BD0923F86 + E786E374FD7F059988C272478C231D4F63830FEEB07747B41BE59A26B39E969B + C72C8D8BA4E5EB2E84DF4EA0E9C09AC5914BF31393DF0739CAE0873A42C6C700 + 06B5D6D8C9AE342376EAFC8F9F666112EEB307DD6644EDE1A282EC8BEB45A63D + 00358C8E0BD2DC583138B090CFC0BBE1ED8B5FAEF10E0A3F0A83D696042486A1 + 14A5DBC1DD1A07641752F3AAA99ED88D9A3F8013072D4B4CABDC411A4B3BDDA8 + 32F002031588AB27FDA1378DC71D028557CA89C1156B86B586CF704526CDC05A + 2A315CFBFE6DC926CE847B70E34EE50BF7E6084DEAB685AED246C659E5B133D9 + 639F7FFFC7CC4CF441DC0E5FFC183EF2DE3D5DB1112B23AD55CFAD2CB06A82FC + 20C953C43CC6F4B779F601ED0BE0AF4B29DB1208074CD3998CFA0FED8B5422AF + 7A75D94F2620975E8C5274494A9B3BF127FA723B31FEC77509E8DA5A6E92E8F9 + DA5F71191C555242B05B247BB1453DC90D9860373949863101A35516711F25E4 + BF4B7EB1354410F8DDBC4819C4CED5C589A15CC43FF1E76512C12FDA951AC58C + 959A6CD6A162E7461116777A90C70F135B936AC3A8941A9E3363D25EE8FFFBBA + 78C364E3F8111EE34BFD56C9704F8882538BBD26E80E3D5D82D1CEF8F0BBD345 + 85FC0D601EBBCCD089C16BE244745D54AF05373569BA7AE0FBB2D368C80444DD + F3E6B8BCA08EE19178F253D4C8E5D79CF653346B9F79DE7E63BBD41613609C45 + A83115AF6E0BD1F04A7C50F066C5236C7D9557C7EDE1229D9B9445A45CC9DAA1 + 3359951CB474DB6B6702C712CD82B36803B2C2599641B9FAC8245A82E556CDD9 + B252C40393B7989C408477A3B0B58BCA83D6E96CC34F7597F7FDF520878FB08C + 44B5E4A659A8E2BD939F32FC8737F6D0EC793D5EDEAA199E24EF64D7CDF8F7A7 + C0B830733A6C14D0E6445B7364AD541DFECDE6A9E3BD2799768E3B61AEB8394F + 0A944D13D8CAB172AF53887964ECA441B59715C3C65F62B0B27D61741E65CED7 + 8C4D9126738F45A99696DAC5F585305B793BC0F775EF6840E5C1B8DCD61AEBDE + 8183D4A56AC00070143FEC66BD38EAE44AF285CDAB1FE4392F45AEBE5B89E96A + BB7AF328ADD21B2A6B31BC6268AB7C2501BD9C0B8B11419F837A971C139D5A55 + AF4091DB9DD2E8AF722A82051594EF17AE2D27FB4A5BCD5E4CBA59E6DCA35424 + F68E4DF8D5A2E8E3CFFDCCC9321E101E02CFF569E64B25DF4C7377602C799FBB + B7A355422F938089582786CBADF7E0173263C72439D46E5B8937849D20B84B50 + 4A1B621B390E893CC789051CF62710113ACCD62F0C507FD5C40F90FCFC00C580 + BA82B63615854AA43829F65073EC110EF4B89EB725C420A3C2DF005CF18C4D4B + C4B047781B82BF17C3CC820FCC7B41134AF14032161B1A50064DEFDCFAC6C40B + F65C00708E887B38D5A0BF1596778ED7E8AACFDE11371C9C66D1EFC6DB1BACF8 + EE0DAD706378DD230435F5216B73B9FCD08EFE2B3D7B60F2C006DE792B83935F + 2B537577E85178A719EFE3BC786D1BB3D5D988F6E9A301C121E4DB127BA5434C + 412DF076D3A8DC8864ACBD2146EDE0BF5701C5C1A517F6D01435E5D471CBCD63 + EC7F252ABBC3DA5B4A2654E7AC8C69D1690252B168633E71635A79A263145D6B + B125DC9E2CFFA30DB01E0866A9616E43B9ADBF8554CB9B311D782AC96652B9C5 + CC7059BCA006B8764E2C2822F02E6441060E55715831371EE67D8FE1E6C74E8B + BE077DB3CE509A4B2CA6B2172265D480569FA66509372659AE8C3285E79EDDDC + FA29D8AF61270416E99F3A5359F21E0BACDB188E8EFFD437EF8B17624C976D1C + DE672037230731BDAA69D8784EF6864871947F6ADB9BDC4EBFB268243C05A988 + C58828BE8B208DD2F0FB9DE18E3BADCF8CFDE2D345EF59BEDD75A954AFFD2007 + 295BC2D6145500D70E48E8B7C3E800EA428FEF7A8AC9DE26451D606976ECA560 + 48FFE7FE40AF3327C79BBF40937FC5C7B45D3510417519B7745BB58EDBA6BBDE + 5FC11EDE4A73CB2E4ED7716C30BC289778F50475F9E2383AF4AFBDE28789E4FB + D0BAF731C93506A1D09AA123682B8CECA6086FA93BE7AE526DDA5C10BE03A11B + 36D59B692DB4EB85968E1C38BFCD060A5469049384964D0C2D5C8088BA2D3177 + 9AAE37753A4FAA458F618CAF666DBB45E6F951C38DD2D528BA855576357B9A5A + 34A563302C747FD6775C48219FD82F5402FB285D04FB8CCB9E6AF384847B2BD6 + 1A51CC992CC01AE6FF5D1666D4235633FB7A14FA2ADF356F825D4DDB1BADD525 + 348167054764A86F1EA39078BFDADD6E0FF2BDC2270454FE340427A158BA6499 + 5F82812693F681AE3A7A8E25F3954C60DC6E5574FC64A74FAD439FACA8E3E2BC + 34096406B4662391843834C272E9FF40BD4703CB92215C6FAE833DBAACFD9647 + 0EB7CBDC4B29093C5DE2827671D1D69AE1EE36CF39D2C78C67ACF671B3F58BEC + 9198486BE4DACEAFCCBE3B5C19CD9C6332FA0391ABED1707E8C1418D60E633C7 + 313560EDC92D6AAD6635C920B412D70F3049B8E1E647A3C0A26A3D50210E09BB + A956133F843A2BC2A4812611D9B5E42E80DC41F8FE09EA5F0D5EF2F83B9E4FA0 + F727200643111DB373A07BD93E55DE8DB7B7ACD63CFD987B940449485DF6870B + 01071726848AE8CD5AB826CD61243400BFB8BBF11B9DC81FD60DAE38B1356883 + 55748E3C17DE0DCEF8E35572D93223944C7DEBFAF6A674FB9F93D5C7ADCC9387 + A9784EE80202625AD0CF1DED0EF0C04A9D795E269C6687654B3F32DA0E595BA4 + 431D9584E3514EC8841C6ABE5BE87C0C46C877A401DFA852B3BCF069761B76D7 + 79DAFC7BF7BF179865710118A2A2E755A98491ECE0752416B79BF12EBF708511 + 0FA28D6FAACBF59806289784E050DD3C3D0E1CAD1DB06FB88819BEE98FA5B398 + 7E6EB5A12513BDB061AB88FC25A5E60C3D8AFEB5141754E99FB42FE1CFB7848C + 42B7A27592A9DB1EB02573BE26424AC128A0DAD9BBDB702A527CA9C2D91C1BF6 + 827F86947673A2968FF34481A82E7C4ACCF4D7FEE19C3F42995F93C020D43A16 + BEDF564D2CFEFC30D9EDBDF382C924BB5405F9577DF69D19FDACEC24ABBCF32E + 62FC1F4AE7D59465EB5E66E533262983A5CB8A6CEA7781F2760189BCF9186A92 + 7FE41E93D44537EEEEEDBFC73A90C9515488A72E112C4919B36345E0E37FF40F + 0DD94683BFDD8936F1B7DA163802A4E2078ACE1908952EC5C03EA7F3BD08C227 + 2D4E9C81200860D71C7F585E549A80C0EC93357DB92A17FCFC234E07083604AB + 945F863056F3374FAEC993C3EEB07FFBB087DD6608E661EC506954996D8D057D + 61A9FF8EE7C09850C5AEAE8AA0B615B2BE9BEBCDEDA33E5C8F570B9F5FF02F33 + B96C7B5E05E80D95E43DEF909C07B08B74F4F775693DFAFA82785FC84CAABF78 + DE8F81B569578E9D878A2E3ED8875E591E883859D6B63E31E8F6126505559555 + 694F1C47D55D0AFBFEBC5FF02BB9FAF8DB5058640A636BDFF548E868034C3E58 + 09A0DCFB629AD5A2159C33AC688D8C44798741AB30E149D6D7135432F3BC6FC9 + 207D9A75988C5D0DEE9F9361F2A1A527543F85FF1F864D2C4C8EC6D3C997FAD3 + C84EC5D2B0670FC53811222EEDCE872C2FF14CB648E100104FE55D16D70366D0 + 8D5CB970ABE75D2B40E23AA8A45B436C46B74383E26BD16E54C73F90084E1835 + F4C194C8E57EBCEB358A9E726B9965FEDBBE73D328D807B23FAA89CF5504742D + E95927E48430235B7B679FA89F92DCD0BF0F6159FCDC18E1D4E7E0D8CCE16F9B + 550710C5A1B95EFC6A9C80765945B0E53CC563BF5C55FA3745266730535926B0 + 264701502355A3FF4173E5815E03F9B284EB82856B8C275BB59D551D455F36FA + 1DF6985726889FFA6E48C0E20E907BE55E8B18BAE30021C82B12C5BC4EF335EF + D79B5D1C34C86C59B2E12F4C7FCA102577D24799E28F91AD73ADE802E715710D + 3A5C0054C6344547A030FC9ECFBFDC659B28F5F7E029DED60A8F9FDEB5365A67 + AC72ADDC17E579050823C44CE01CE6C9E37E1B5B52B5C6062FE4D5EA4835C3D4 + DB41E99BA4A050F14FC1A93BC1F587313D13C879C3955E1AE7E0E853C04C7488 + E0AA49EEB684B3D184C5A9C573DCB1726F39C1A22AFF6895792129CC824EFFCC + B5E9103A21DF34184C222C9EC91CB6372855C4EBF9097D47BFF3191FF4FA02FC + A327EB15325668EB91D2A3B2F6C8BA70C900D45C272D12DDD6F7B368D8C694D8 + BCE5F3C3C1B67A20787D8C4DB8435D4A64F796CB1DD2A8D8F121C4B089D97D52 + A4514D47189E6725DC5E67F4F6F8E4AC73EAD99398F4F3190C91BB29ADC857EB + F2C3EBDA21B57779E3587CFB4EAF69DA0771F62C82FDE4936DA542E75C212DA0 + A79AE9BAB50F663F5EF07A9CEC5FD7AA1B073ECD2D1CE568E95394E1ED7A5E88 + 77A52BED76B33AC42DF0042BBD3AF38E082AA2A906B3940B78CD4BD9B02FCACE + CABF0820B3CD0D9555D4AB49A5FAF1727B323B594B9AA4C8208040887DF1A176 + 446F1792DA819E937E1CCDAE6A40D4DA361B71336E735243AB176F831F4E04A2 + E18E5C5BA6D3A1FD58B5A3886824B73407B1A13CC551408F86516B9B5036AE70 + E6A683A63C948F6F96AF5FDC07323C4777C12BF92EADF056DCFE197BEE2E5867 + E7FE8538F22582E327319EE6D5EEEE6764D13F86E3F91320F9273A6F9BB726B0 + 71544F98B11DB908AB7151A130A5794932839A8D571641B582C7F7CCC0ABB1D2 + 888877C98ED0345EB83593CB3B8EB39F393542F95573752BD9B8F72493B0CB1C + 67347D392568ACAD081335E752D6AA1252503DFE68AF39ADE61B761EB9E2D2C7 + 746CDD16EFB036EB091739BBE37441AF692C6649C20102F77C803B4BBAA5FB65 + D9F89A68CFE39A90F0F078A63EF62244006088FBE3FDE42B83CF8FE7FFB597CD + D9476496E24AA01158AFC2EE552127F27C9D7EE3519CC97B7105FB4FDA9716D0 + 660700DA9A694886983CE2D091D00A7A81EFCDFFC257810E94CBB0A82513EBC9 + 2E4333D7FC1564C64F75C699F9DEAC57C5FF40130C8321679DAD694E83FDF29F + 21602BFFBBCF5CF5CAE2A6677F052B5D4DDFA5E8D620CA684509390415D8A4F8 + 7C01F5797BF88728B4A325723E7E07D862D6923333E4D103E0DB8A69C6886FB1 + 41288D6EA1DFEC91BC1C7A8CE4EF24F87D549C8292C64630808FB5F6B10B92E4 + 6D1C2E66AA0C8F86F5EE597941EF8AB371F70481FAEDDB10DD59CFF0EFC52578 + 5996C155253C855D1A1C4174A7C0EB78C3260C6AF5BBD1C44DB58C14C2CD5780 + F7567D1D2A757EA9D84DE1C1668C1D750587DAA90CAF7D533974428BA4A8D3BD + 5127D041D3C17E3612563D02291EFBC2B6780C63DD160060ABCF4D3426D6A112 + 687A97A19760AAF236B23794E0796456C803AEC71CAC96E06AF0CC4A3D728EFF + 85D93A9491DE0F84BE379A44C019C97ED1AD11315F9B1F82BD27F71EF07D972F + 602C6FCD0E207DBFC4DD176A5B1F0034ABADB2C2C66422F8C81870346567A49D + 391EB35B0D48024B8D8D14F688F1E3BD752B381232E925D7E101144320922915 + AC050D139D1030CCC23A3D01A5BC49AFE1E5644B07CAF54C325268CCA263A51B + D0EB27D512B0190FACBE04B4CA9D9F4DDA9144DBE354460CC5FD567184D16075 + 241EB73EEE74C95042B4E2D10E90BE2915B6B8BA41CD4E250A955E6500E6172B + 18989214C166FFF3E14AE4343C2F27DB0E6B9EE7A3C2BD9540C73870CE735ACE + 476E99C7982F55724C127A95308357AF7D8AFF9CDA134FCD191E380A233F786F + C56BB039F07587F3CDDFCDFEBA24CF241846B892EBF7919E6E25DC1B91FFF382 + C5B4DB262CB21C9B10BD60A25A14C0C109AA9110888B8AE7680EACC36137C261 + 18A80DAB0C569EA522FED30A88FD27416B97E8596E24A42F943B5E92397C949A + 8BE527A6AF9C2D187AEE290276D7D714F8F99C07A0DEA126500D8645CC23F429 + 591E7FC0787C793A3487570214F6AAB7C69987FFCF5D9C16BF12B527E2FCDA67 + 115263753D8FE80C5C97B08B381E5BFB719A4802AAC1E9277CADF4C4C0E0E767 + E14F8B34BC8076AD9A6E02615AB5675E54A2BE3185D9D5BF04482A6FD4A42CE6 + A82DBE6E935B37354B2E6AE68E4DD313589F90621BD398C9BCCDB5BBE25C2DFE + 5FB1AC830F960C9A30266FC1BF506957F6E28A5C438398E9F8C043390E61184A + 8DF953B03DF47287A752720DEBD487AB29E12DC3C9432755FE72CF722B60BF2F + 90D56C1063A6DA3071744A55D91ED7241F28C0AAFA381D473FEBC3E837D6D72B + F262E28D001319EDE1615744328DD383B97DFE912D7167E96BA8C2957C6D70C9 + 4863F56BCA7B15447534379854F7F5F52A91AA7F92028923CAA9A86522F44716 + 88CE6659BE11AC9B766DE5EF215363C9E96E8444631703358E2F88B0B72C0F0E + 2E3CE3E7ADD0FD5E16D7B48E26B5BF89E0C7289AEB8D6CB26EBE5E642AED2F4F + CD5B9AA5E7F4538060D880C10A8A27AED704C7E11B44F21BE0C7B78A7319CB76 + D22B9A62EE8B103E006F8966D9B5CDCAE40D76CD1A3D3036E20D55FE80B7CEEC + 3712911C2E58B3E966C043FA1FB941B69211CFFD9B1CF5F05F38887C41FCC26F + 81AFB878D21D3545C5360D986478CC0BE8A7BB1DDDA7AD99299BCA6D433E2625 + A7167EB71A366B807D1D5AC890F3F2DB4E1A226374528B0342350314F6665592 + 7DD45E2B40BCE80527900EA1CF1B4D005F2AB0EE26D5747EFDDC96ADF8E19497 + 5FCD9BD49E5B190610B83554CB4686D06F1CB93A7E8CEF396059694068FF920F + C406DF73E396B34BEC408E29838311E27823EA9CCF709149A67E2D84F7375385 + 68F7795065F80B906A53BF01A07680FD3E2C24CD4EF9B260E53AE31E187EC8BE + 84299126CEDB69BAA09F2B17E0D72BA17524024E5E1584C1B439AC91370B92E0 + 7D3F7800B8EC019F0D56935A2B90E27D7533D29895ADD82A0803E26FB0D11DD2 + 2BEDE3394FA15874923C2044B3D0F2BD4654319C60613575F3B90A3377879106 + C46DE7963795B9794F9BB762FC3A4F5D3F336B559DFB976B11575C02B518142F + 1F79DAD205999137BF710DA9F07CAA9EDCF36D271730658EC1B6C77A8BD315A4 + 87C376C16C67D147312AFED16B20477333C0B5E5F4D679CB72E84A50B8E6590C + 75D78783708F07C054F9A66A6CEA87EC005794D3A0A764D77F9FCDD730E7E78C + 32C6ECEA7E0ACD8576B8EB6AC15D15B196F7D1B69E73D1A97893152F803EFEDD + F739644B6BA6F0039D665F889E32838DAA53975B151BFB13789CAD13B763E46F + 120BC0EA5E98F1E0C553E1D0571F02058256EAF39EBA620BA5B7F85FE0DA831A + BC4FF4F5D727A9FDED40254F20315F082486894F03933E8EDCABDC2AE49199B8 + F48676C2CF28F5DCD1419369D15C6E6B0FFF7F88A364FDBE74069D2736230D97 + EB3D44CB8E8389999647E0CE9717B90B06CE3A90D80DC3A6AB244BFD6DF8654A + 6AB87154969DA60C925C9B1D835676F664C8071B759E793699D39E1201594647 + 6748C2E2DDB86DB3F1344CF1370C2AE64CFF73B45BA22E9BD81EFAF37AC891B3 + 5200390DA867E09109C020B9C88F3C70E8B567FA7F53EC60BABD8A897EE35769 + 8B5B1C460921A92E8C7C7749EBFB64A73F68293E5E636C5C76A88496FBDFA1C8 + EA2EDEDF4C8195660ABFEFA89995146354C09BB3E1CEC1E97ECB54876F119DD2 + 66E43004E536609F2E71173314B48C7AE4BE11CB03A63B6E919FBB7834845ED7 + 6475F08031CAF25706F9926E7727132E673A420530372E2037C81AA68F6754BE + E6303008C47D44C2A7BA9F29973939DDCA85C08E2988FAF3FDDA7EEFE8B720F6 + 1029D2A233A1FD6A88CD502E482E322AA51BAD096E4853C899A549517D399EC8 + 679C8FAA3300ECE21884A5A0A8EDDA50060B5D73519CD6BC8CB691DCC3A8117E + EE303C52E7F447358EB27E9D2EC315719FF860C2AF6768240F07B2C329C69843 + 124921A6FBBDEE4DFD8941D038E3EE11AB40BE5E41217AA4A955841508F6C6CB + 9520B3944233F42B405973B60D8714CD46C5B4FA3D68F84A98C142CA92E915E4 + 95F9479D9DAB9C2B327760DA044A8C4652016A97F92CB6C2AD95A931C28DD8B5 + 372FD47B1AFFE4D6A41E4A90605EF6281457CA39DA4F3112079049E0EDDDAF9A + 59EC90C67BF374E503AB7F9431319C0F7844803D990DB3A201CFE972995113BA + 1FAF68CCAF9A8102A4A0B89FE4FFDA21D0062BC69C66F6BD931B130C4433C05E + F7C848E8504ECEEA331082C3EE47A216052999521A533E516B855581017E0611 + 3297FC035D55B2FA124380FC9B69CEE7834EDE3DCCFD9A488316B4DBDA3004C4 + 4A8FE55427AE77C38A1DE3DD4658CA81F310B68C8180DA8177174A544D137117 + ACFAB5767582196C685F20552DB00FC3FFD21C80DED3388123F6DDE7E5C22591 + 4545E123BC88E7AD47BD541CEF88EFE013F5A73CC6850C816A10E25E5E60C164 + 86AF283B9A6427D6873D259C780AA9717336F7BF78938C77CFAB90E857A3ABE9 + 671FF7CF70D5FFD1DD36FE3F456D31199BEB04DE50AAEEA2A128F54CFED44999 + 7572403443BC14D8B3351DC6D15834D3C4144CD1153ACF1122DA9F3CD792E74F + EBA7174C217C0EF212C798A02BA9599C989B989596EFD1CD5D970BDB22962BE9 + 2448CEC2466876342EE02A680D64EA12CB4F5672C64D7D170A6C8414EF202AE4 + B62E07B99B0B642C9C38040C90C1621C610B72743F78133DA9D355646BA113F5 + 226A38E1EABBC2B5E042E0305B5B10EFCF641F4B0165360092134CD0F2D48CCF + D6A0A18E9D321DAF7E578319E46657CD3255C36078726B8D218DE0F171D2991A + 28F1E2AECA9B492D6A8B8F60BE42123C15ADD51B88CDBBFF2131EBE33E5898CB + 0C3C2A4E9416CBE88DE97A73C2939746FB886A4204597919571E94E04852AC16 + 5A1DE09F77326E6AA13F99C834C76B19C236A576D3D1A806D82EBBB38AB1D02A + 5D566D5D38B987B30E61D8ABAFBEFEE7AA0885E4ED1C6E209E0A86EED419B050 + 735DFCE6540C847ACC36C98AC63B392A784747A9710F4F8756E7A4097BB3A5B2 + CCE68DFEBD0ED42AD4A3DA0EADC940C975672B4C733EEC9B65F49D219DA49AD0 + FBFFBDF9AC4E8583C220C09E5AB96321A1BD005C1F9753C404962187A3F18540 + ADDE7FA34CBF2CC48F2B176BB3466D74230C015EAF3D286D327002835B7F34F0 + 0116F40F4C78830B799F062A1C2439B1E80F7944DF5CF4C3764EA1CC524D1572 + 9EC959BA3481A0D222662FA5BE5652B9490946EA1A1C358592F88D1D5162485B + D61FB7FFCC3EE60A5731B9328185D4BF47F4E02263A8FB3233C077EAC0FCF103 + 1298003E70C22E97B75C2DB7FBE5171EDA5334FDE11D3D9900EF0D444ED848B3 + 224FC5E783BC0462D526179FE17854A13EE4CD01E8A6806BF88B4BE0A2EC6465 + DAF606C38A416CD0ECC1C9944A34E1258FA68D27CF1A6BDE265A4B981ADDFC97 + F9FE303573CC32B190EC67E9A00FEC3E843CCC5B4E920E05158C291240F2234E + B0855E5826F6057FDABFBF9616E07DEF2A008FE15B26D803E33E475CE93D0910 + 6C15C4053A343A3CC1EAA5729046953A4A4F739C8C003C72C9D27CDFE8E1E566 + 633672BCACAEF5258982F83A7D4115DD23A2662A7E494C5F505C088A11B17AAF + CFFB1882E425EBA785FD5CA5BE01195F0F1C7EA1E8E71A46B52EA37C04ACB669 + 1FFAB3850610C19A69C944FFFA449274F90A24C1997AA41E4297EB8BF698B946 + 069830BFB57FC797E10B10D4597AC08A02493DB37DBF2EDC4E0957272D0623C1 + 70747E23A886D8DAE42C780A9DB9B28031F945D807F34CF6B9120BC18CBD7B56 + 4CA6B6AAE53B5CDF2A5510414097535A78279A33BF134A6507F3E1CD897B25E2 + E06DEAD887C0C1DDC80AB980AC597D734A1D14ADBFF5F31EA9D5A7F0FD3E95B8 + AC0A231C8BC56DAD157405D77D632316E5D5F3353E412121B2B9D60781C51E84 + E0C77853878687A84F622A33DF1F211C58E6CF84663015439896464E4D93AA42 + A86FD41BACEF8E0C0E6F0A2422ABD07E80069A3FDF7013ACD978697C39626C95 + 9BF64A27CAB3559952767BCC53A4EB0B1BC7BA0769F629A36B928CF823126440 + B5CC2A47B31790E3EAC3BF45F847089C10F41CEA57D0B5BC6CDC9265B886B0BA + 9405E0D144F9A2D44AC8ED84009423F8CD950595247607B344B2D57D184A87C8 + FC2D6C178CAFED55C26FF058A68C9942952C8381EC4CB3958CABD572A8B10C81 + 4F48727BF9A2870924ECCE293C7DD200EFD596E34E8755719CBB698506A3E703 + 9B51A36CCA90CEB9FB1949CF3810CA490F90EF3390974C6494EF9E4077D6640C + 9035F58F9409EB01212B5D5C9BF1B9FE0C410013AB7E27F029C91F29EA82628B + 1F236AEEAE09974831AA29034B6395CDEC2D4E4154430CFD49C80BD2345813E8 + 534C47BF7A8DAA44F2C8C19292FE5D060FE82E93C3281E4B7AF3E32C6C11A144 + 641FDF3A66179F9939D65458938FF0EE47A4B2A2E2D4C7709618D503F2C8E25F + A6E6516C09A2D530952F33BF8613FF88231D1EFD82A2E98AE426730E628DA8C4 + E17A7E494494A6F563B9A32BB2F5147D9A1C227740C59C6597BCDEDEB558FC69 + 98E82AB2D90CF97B8E9E9A79874EBA37C473EE0B38DF7D8BA5822B01FB27EFE5 + 2FB88266885B1DFA76C0CAF6C6B8C73C9D16905DABC51AF572D38ACA13DBD66F + CDE12EB6B39654602133D6028B0FC1A06396A2559C27FAE8DAE41F576A7CBFE7 + 7E1D29E7249B6193DE3E95D026B38FE3792D869DB9A1BA80473F63267C35B550 + 334DC1751A7D63DC1063E1FA6EF703465598886CD12EC8F053906AD268DE29EA + F8CD399D098682F3EA27308135AA3AB0C8DF07B9EE27F610DD9832B5C0528643 + 48BD2328463E8E5BE1B15A94AE19B7EF0C77841A8C769C600854D9106F9A0604 + BCEC1B9BE3947960EBC8D9F5F92B15DE406B4F760021E99C8513B48626F38A09 + DD3C9B9C4C47FF3DB9509DF765ED1B26C0505AE6A27C7340DB19F8EF40DAE260 + F162A96A1B7F571EBBFC6541CFB57DF82B32EEF7A0CB833897CCC06B7E3913E8 + B056DFD014D33DE99333DE706D482DD08E41B900DD666957B33E9624FD39403B + 612E210737AF17176C30B611D782811A891BE63309530DEE1DCE7C9C197BD559 + E036B00CB9AF9586BFCBFE3D2EF227C785D00B2E3D27CDF4F43AD04F39609E02 + 31FBB8F8D1F991104A3B660E1F78A5D5841B2FE31F6B94C8BE853F8CBA2B93A3 + 75AE6DA6BBCFFAFE56BE02FB24DA7DC8C22E3DC7BDCDCF3D97D6462DF5DA74F6 + 49496152B2B2DF6674800250EBCD83B7CCB0B2240F5F13F5A594E2EB3DEAF472 + 429D74457F1C96C6F909BA0CC7A9C71A4278814D96BF649CE38D1A22DDA6D162 + BF2CE20D8A271C5038F5567A92A0AB2B1C6F5041357E238D8D05A407FE086E59 + 77D3FE12899E5CF33931085AE6822808F00467EA7AEB53F5BC32A2C89FF0511F + E84F8B4233959F9664BE022278BB9F1EC77C1EF96C0AF4787756897D9C797909 + ECBB6991058DD86F5DD688C8526E5CFDC219B0C30EE0CDFE28A0BC9424442ED9 + 9DFD3CA35879A5D19FBE17FB7E5D5065CEDF21E2E49F2879375A84295085B04D + 11871A32124DB1C0B9B1F592938807C8ED46B070EB723FCFB97D0A50811A2FAF + 8E3694685BE1AF729159AEC34B56FA42ED136C6896B2489F0E7E2CD112BBA18D + 5C53A25AD462C280372C86F4F61C67DE0BF6347F0630B83D6BE6DF28C1DAAA31 + 275330FE0015EA6454E0AF6295AD760855AB71CE6E4F1C9E3D59C982E8653008 + ACA4BD500095496EAB6A5F3EF9C14996CE92DAA4D05FE1B5FB77EE765BB9FA8A + F71202C2C75CC7D04A8764AA4CAD559442C5273BE7FE698996867B93885CF542 + E1956F22436FAE734E364A1B88B0B7BA1294E8EEA51F513D6E0ED34F9CC001F1 + DC90744FA656C13554EBB52C891C283546B72D009141593DBA3EF470FE5BB2E4 + 78A29DF1B4DE1AC21FB941394AA69DEB60A38F2E022B185434AC7B33D3E29FC9 + FBBA5EC1C13730744A4C3925FE025F0882EAD7327AB2965780EB53E1B6E00A8A + 9601EF6A9F61BC0A6852E3F5CBD9E6564ED238887BE5218B49C57AC580D8B0B5 + 6DB3D1915404C07226D753488EC9CD526578B25BD0A6A58C960EF443A0EBE3A1 + 97A82A43DA19987FE82B22B8CAA8D5958394BD3430B3F434AD6E38CF2D234CB3 + 698B8CA0864C7F613D1286B9BF0A9DDCE141EA85CE0C6631371AD35C3A550849 + 80E333327D0DF295C1D33DB0BFEE46570C565FD8DA1EBB09780582B1047F4627 + 35068AAE7CF9825B2A7C6B4160184EB64106AA975620E513336AE446EA2D4E29 + 0BB40222005D24886F9DF9ABEA062EB9DA82C5A8D853F1E018E5666580652B29 + FD3E48B30ACCE66AB83E9214B7293BA77E3DFA95AC776684E3545BB533CF3CBA + 3ABF0D6E91CC907A3DCBC7166CB326B1711805859DCEBBEA86D2E131FADDE03F + 88558802744833EB19DB2B8DC962BB29B4953DCD4C4364E9DAA23F610517C66A + DE40FE3F3DA4C5FD968FF101A14FACF354C92451D63A9319DE7720A218370DC0 + B140EFB9041BC9D717273D5DD2A654B357241E96E756C51B0A840E14CFCE8748 + 25FFEF84F8B7958C48F5812BCB3C14AE0522D87DD71D06FBBB5DAB19418B1095 + 5C3C7473CD200D4673F5F60FF3F9D62D266DD6C1BCA6649F724677F7BF3EC0EB + 974DF12E89357EE3B6475C6AE03CF11229D6A862A91D7B6B24AFAAAF1245BEF6 + 80A38BF3F194ECF244C625813A0349B19A956A01CA584F49D54A2336C50BBC16 + 6465DDB33A87C806FD3CD980175F8D12A1724F239649F3E3FBC9E73C1EEAB85A + 0F936C032DFB182C9616A5AC2B060B72F3DAFBED671FB8DA10B6FBAAD45280B1 + 371D664B38E42FC261CCE66D78FF1278A786F94E7211D6D3244F5ABE56E572B3 + 1F4629C982229CED14816B211D8552870D9D78779B338B5076EBF4DF54463FB8 + DF7DAEB5AA9C6FA3184E746D91E7F7CEC8925A0B56DB4D87657E94D80427560D + 89E845F4BCB714D431C884AC12232C97DFE4EECE6FC51364B5A1AA644F6645A5 + 360469880810315A0540463A7BCFF3EA25E1254934D38228502B5F254EC5557E + 8E1729808D961473AA91C8271E69494D6DD622CE8FD95BA9C956D4DED70A447E + 4C0E505E9CD1CE0619253FF5776526707F535A8938382618D1F9449EDBDD16F0 + 5B0A0AE8927EC9C063F923F0C72FABB68A5682FD43949A921B68EA37C6ABC9E5 + C1AF534FF272955E4743662BB8D3AC0EE71B4DD8915D4A7E0B74D2D83064A60C + 26E9A36E8B8DAF0CB117E98A52445E1E15C8D1B6267FDE1C00207002B7D75BA9 + 48C3D2D4FC8E214C74007BC4FF71F124E18265BE1F2CEB42780ADD9FC4BD1994 + 6F78E9DFE39F2C0AF10630665669152401A971FA6AF5AF58C57436784AB6D665 + 5443C5E6545E094E5EF9155F053F3DB906A3093DE9A6A96D6DA0040E3BD17A59 + A1A1BB62DD970CB01B9F855E11A658236084CE79343917398C582E494D5B2C4A + 3FFF741596504737E8071B14BEEF76B38B9F80CAFE85427930AEC3D6293B040A + 919B253C3D2D5C508B44B6C1BF2023E49B7BD3623B2640448352CC834961057B + 13399B9F94114CD17CC15D36A67E77401CE9C62FDA24042EAD275EA06F8BAA75 + CCA9384CD1A623140147D5A3E2C4D9023EDA17CB5565A378FCBA9AE4605D8159 + E2E1DA3574FAF160225812E1D246C0F67377AAC31B32DC0FFD02075B0A141521 + 8DE6D028039B8328140BF309B92A19588744282711C18EC092D7B9E3FDDE62DD + 396AE5AD31852CDB72EC25A62C7B980D32F025EBD12A86D93FACBC3695E48709 + 9EFF3E950BCF42EF05D199405EAFDEB59C396FC9B32F9328D947094A75AF47A3 + 74F8861D6256BED3B256FCA8E1CA348117DBFAE58224D12F7E63CCBE1C81E10E + E5C1E5087345D278422D73D2013A46401469C271F393516F8F60C85BE3577DB2 + 29639EFAF1C0B73DB4DEE296D7DD1B48A8217A7C8EBDDA48D00CC66F8F10569B + 665132DB2CD36299CAE1DD3BD463995ED6CA2EB55F0449688640D4ABA531F512 + 83068CB7310E22EEAA7ABA54F1C23FBA6CAAF69D9B5090002BC1A58596801B48 + D6F7F0A3F9BBDA9A33C4E0B09363638251E6AE9E7DF4EFF98A9B0CB2960988CF + ADBF30E008D51C57B4272A6A283D0D0B6A0B9B3DCD99B443FF3C6EE381B5F41E + 3686D60320B2026C7E8463A80BBC6A695F0226FF59ECF3BB9F6D88EE57655CBC + 5432E49CDBAF76E4B810C74C5858DF8BC93F9DFA833EA4F008792B97476EE52F + ED1A179A2F620A7D9C25BAAED03AF788E8BBCC16F2D2A84FFC603A13CB15CD13 + 3AA8C30FEAA07AA782CD643386F227FFC53118AB803EDDB21E9C8E5E4361EC39 + F2C13125EDE1A117580ADF0900AB5186AB59A32513EE57D74314850D9837EE4B + 71F64FD5BABBAD0B534BC07C2F9B1C3A9DEA07EEFF58D9BBCF6B13340358C531 + 3F80903944378D47CEEC7A3EA4AA9524C022D055C60C49292946BF11537A19B8 + 68CED82A565589EF45F110470A0FFFEF3DFBCCCE95880795747B09726FB302DA + D0BA1DC769622A41188C0BE64C2205F9C37CDD208DB32742312794C18195A38A + C2FE053C2AAA7F101EE116A2BAEBDF02F215A67D13D9A97551077E0DF65DCFF2 + 283485C6AE384031125FEAAC23387A3AE0F895064BE1FF300132AF508D5319BE + B5A88E983389FCC4BFEDFB1D622A64081F33F8CF3DB7934A9DDD985551391216 + 01E4CED70385E14FCA742C5D131320F4FA36EA14085A0F0687A5DD343932A661 + A74C9F08C71BEBE3B558651713EBE8131878888100A66161B3D6420E97FCEB41 + 3C4946D6A77E40AB2B2F9CE2113B95BFDC318A83A64A980632A56ECD3CB27207 + 0F6226A249734D4F621A35C0CFDE45460F6356E55FFCF5C5C0A741C527949F5C + 91A030E288DC4CDB3FAA42C7C553DBF5DD53E2D565466B44CD00AA6051CE6FFD + 54D1C469181F111AC6A60A5ED5B9CC5EF038930F4D6577CE428B0DE23FAED1E9 + B4B7BB5DBFCE0F2F3656BAECA2F0A72AE1C347DFB9083A81C4A3AC1AC47A9426 + F80C528C153131D2AA0FEF938682B50BD64F7DA82376E6993FA74DDB3E435459 + CD18D08587A9FF0031C5144A6E0C26D361D394527A589BD422D2195FBE0CB676 + 2957E65B82A5F8CD6F8D7C62DB402E7D86B9C9D4DBE87D232CB43195B36EF297 + 286D3E5CADD6082625AC1C0145C12578737BC81A374DD417AC33BDFE7C562D27 + AC42F80CDFC70ABFF2DB37E6DB49A11ED8B11D5CD8049472BCEC512AFA5B1A7D + 817B9F2700F77C7ECB0E32E02E6BDE6B036490408FFC958DE2D2038D4816371B + 213A5F144C3455405952297DFD03BFD299E2194DD38D37C6C05402C7A26A64BD + 1FB5ACD42F4B29D3D5B94672E8EAB91AD0034473CD016FDE46338F7F152641B2 + D29EBB0E96C9D642D22E1546D8504891244875F04C27754EEE76E77D3EFDAF2B + 18D3C3EFDFDC6C7C1223A1565E5EDDF5F8102D23EE297910FA2EE51C9CD8514E + B24325AC141A51938505E9CB39C901FE7B71063D59BD28B49583FF1E2FB7FCD7 + 287CD3B59A6EEA4E435C6AE9195E81341F351F949816AD1569FCB3FC5C2C4510 + 6F39C68CB5BBA40C6F068FBF8505BA2E4D69B5406EB1EED2238209A4DB4B2BE7 + CE4B2667275E391EECFA11F6C8A95CA4965285D5D407A367F2966C4CCFDD4A86 + 131FF6173D3CFA883F74B7A10C9ED1E0F0C94C70622EB2E81FF90A7E3D5A37A2 + 535D121E97AC01CF8200C4527403C996046D0CC763BB174D01ECA999B8279A55 + ED5CC502D80CF4B5A3A7515A0081137744174EB2FEFAA49AB77A29A6D5267968 + ECD6CF123A0B26314FD80CC522C689EA6E753B77982E60E14DC072E0F5D5FD46 + F01F19152AC6AEF91CF20D5A019F46D2394F5A21C59D74715464E5D830722A1D + 3D982CF0BD90CBC5F0D46B8A329A03EFD165DFA6BEF750EB9753DE4D94850F7A + DD416DCE40E476CA5C468F6C19BB22629B1AC5F794F8681AD4F79A7C392165F9 + BCC162FDF8C453DCB621513CD620B1C2283C1DE308DA10438DAA564A1B9A0A24 + 3FAA066EEC34502842BE1557B11162EAAAE744B16723E4B89F88B7D051D3AEAF + CF763141BB654CC75C6040C609A1C47CDA31D79974ECE0AEAC792D7A18C1570D + 2A24D816ED2E0C05A2AECCF2EED64368217546D94F421AC68DB7E6FAA34415B0 + 1AB62B16F558C593BEB9E7F1FE4CE84A530321D29935A7F2BEA38B35576889C9 + 4B6D69CF9635D737CED4F9AF3365A41698F87C7DAA7D28F84A74E1569ACFDF23 + 96BD0F48F60B377FCB07C158285733F6F6D7FD80F994D1D9BDD9B91809C6C7DF + 7AE5FB8C273D0C4D9AC248984139E89AADC3C37C794640AD404DF32E735A7F72 + 05367A23013D5C794841CCE0AB25FEB0FFA7738A546E014279 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + cleartomark + %%EndFont + %%BeginFont: CMTI7 + %!PS-AdobeFont-1.1: CMTI7 1.0 + %%CreationDate: 1991 Aug 18 21:07:18 + % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. + 11 dict begin + /FontInfo 7 dict dup begin + /version (1.0) readonly def + /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def + /FullName (CMTI7) readonly def + /FamilyName (Computer Modern) readonly def + /Weight (Medium) readonly def + /ItalicAngle -14.04 def + /isFixedPitch false def + end readonly def + /FontName /CMTI7 def + /PaintType 0 def + /FontType 1 def + /FontMatrix [0.001 0 0 0.001 0 0] readonly def + /Encoding 256 array + 0 1 255 {1 index exch /.notdef put} for + dup 11 /ff put + dup 12 /fi put + dup 38 /ampersand put + dup 40 /parenleft put + dup 41 /parenright put + dup 44 /comma put + dup 45 /hyphen put + dup 47 /slash put + dup 58 /colon put + dup 59 /semicolon put + dup 66 /B put + dup 67 /C put + dup 68 /D put + dup 71 /G put + dup 77 /M put + dup 78 /N put + dup 80 /P put + dup 82 /R put + dup 83 /S put + dup 85 /U put + dup 88 /X put + dup 89 /Y put + dup 97 /a put + dup 98 /b put + dup 99 /c put + dup 100 /d put + dup 101 /e put + dup 102 /f put + dup 103 /g put + dup 104 /h put + dup 105 /i put + dup 106 /j put + dup 107 /k put + dup 108 /l put + dup 109 /m put + dup 110 /n put + dup 111 /o put + dup 112 /p put + dup 114 /r put + dup 115 /s put + dup 116 /t put + dup 117 /u put + dup 118 /v put + dup 119 /w put + dup 120 /x put + dup 121 /y put + readonly def + /FontBBox{-27 -250 1268 750}readonly def + /UniqueID 5000825 def + currentdict end + currentfile eexec + D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE + 3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B + 532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 + B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B + 986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE + D919C2DDD26BDC0D99398B9F4D03D77639DF1232A4D6233A9CAF69B151DFD33F + C0962CCA6FACCEA6B71BEEF7C056FBD376F2F0D0BD6BE0A0A8259139B28B99C6 + 25119B8C60FF7BA002476930DFDC2F6B1B5A80F1C0E544A22E3F0FB2FEAB64B6 + A509B61E1AB96121FBF7F2BC27CDE5B4961048FC2169C8DB745FCC7AF0EED507 + 284038B15CE53E69AA22CA76C2A208F6AD8614CD500D479A5E0FD25E7BB14C7F + C47C503E4CC38975CB0A8F7E109665FB69EBAE6EB68B2D6FA3C967D5BDE7830E + 9CE6F13DFAEBC852DF1D7D0CDD33DD4D5CD6D94DD8AE0D48AB638013CF75A25C + 04FDEA8775EC52A13AF40FA41F7354624D917EE620318C702237AF8C0E1FFA02 + 127F862D4DFD0A56774235A881AFBB8F7F4BCB33811C581CFF38462F669B7F97 + 1F97AC09373B8F9B7E653013AF8170613E8D7E17235A893BE296A0CD2096B71F + 16778388993EDF1B003EBCE23DD02949CBFAAAB5D9F6A08178BFB8ED1043FC1B + 0B90D9AFC27B19783740E8DDE0E5E01D116A8CB083C721FBB8EBF71018A9570E + 78590CD831116BC0FDA4229F79A581874FC3A1F108A4FCA80CE27FA54A2A7505 + 5BDB3D52E2595512837732322FB5BBE459C0205EB38439E34A39544F0A1567C6 + F29FBB7CF931708C8F92786CCBCBB443D54462B3B4B7BD38E90D325EBC31BA05 + FB79C04C716319BB89139C80B8AC69378A13AB1A14B3E5D1EA15CB5936D07912 + F4BECD821DA4B42857AD100F76F457321157D8552D351A76D3C4CDACA112DD1B + 17A8E6AE4B2506AFCABE4B1A4E16495D363BFD4C8D85C255A2E1DAE06D5E7837 + 3124D9AAF134A6FAFED3D47621376F2A305A4C116A09BB5F7230F12486D1E6CF + 30B0CB5C4DCDE4313A20E0D99622392924BAB6E832224FDECE1467AB597594AF + A0C3E758C7923481724AEF648DDACC0BBFAC72C0B8522C71FB8D2B44AA31D02D + 32BF258077FE92439A336E25A5EEA4F005BE0C4AD05006D279FEDB6E16C4339B + 54901338D5E1A3E29FA2D175F5D561403F256D4C4D4F13A0D7D3E46FE4D1662B + CBAEB089073761021DAE7F2546ABA8822DE76F82F4A9C02F2711CF1AF839A4D1 + 04F620501C8A0F1AC338F6FC9C685E9FFAB7A731EB67850E7F5F64BADBEBFF06 + DB2DDC9BB41A721B8A9A5B747D337D50195330EE10D0125A4F7B86EA925946D0 + 05C2702B5181ACBB62640ED098A4795277AD845ED9198CF24F32D1E067A9DA1F + A1BCD0E91E552C5C84FAAB8601A0BC145FD08EFAC60039193D2B4231BDD31479 + 85BA67AA430D04B85B440B71B3504F85F9C74139A88051EA2F1CAB645466E4F3 + EBEE24815C85A91E8B79CBF161680B48EF418A985A69CDAA7D60B76DA60BDD3A + F7012E574E7D53628C798519F96A2075F2D5EFA84A64344A6F7AB6CE98C7D2DD + 42F741DBF3000B49BB03D51DF1E5BBA3173C7F91CAE79BDA8E33B48F80A489DC + 18DA75A8C61A8FF3AFD704014E7E61759DD0D9B262B3280C530F5951A795CA15 + 8385CFE616B6C9BC427E0F95058B77BD83F26B4329440EA253EA15658D04657A + 2B06821490DDA5974B9C9C9040BB1DD492C1A0FEC55F158068F6954DAB1AD097 + 12F232E10DB750B376B22DE66FD7CC8D8D74C4435818398356C626B40A1956DE + 8FF7B1F56A2A3F657495E648EBAB5698DBE34A1093EC052A2E5046EB608EEE37 + 61C3288F1A1D39EEDDF702ED98579CB56CF852DD0EAA3E92BFC7186FBCB1F8E2 + E9DDB4BA9909CC7CB96AB5637F16B47B8AC456AF2E6AB067DE83A8C8E4765B85 + E3981A4E1F58677BFAB17A8F374708476CB09289DD3C14FEE335FF4E79F45A84 + 7EA7EDACD9CE8E0D91B78BB1C65D6B54A1EDAC5DD6B7C11EF014B6157C345F76 + 520E09A474EB462937FE8DC4714AE9C35EF7E2AF1115848D0F07AB9280242129 + 144EC35B954F793A00473FA898D07A75F2B6A8A352E04645927B2FD5BCE5ACDF + 2214967AC1CE74CAE81FAA100D228C623BD829579FC02B88676172CFCC1CB549 + 03736A137E8AC64FC8EBFEE8A55793B56D1B458F6454EC7A6FCDC85443A9C165 + 112EC44FB510071E2AF7A5FCBD4DBD4A36A7EFFB77D3F2975F3BFB764A4CEE27 + 0A7BE30752D6F012D13572CAB7E34B8C231E27C5B22C0C92F6D85EF7CAE0FA60 + 13B91952C95A51457FEB2F272F60E5DAB181289A698BDAEFA75CC9E85E801E01 + AC45184B5EEF567C1C584E78385D0414AB4627774F7311EDE8F42457E02E047E + AED6510CE40E124FB2DB17A15CF8C95F97D9F9D31B17A17353B45768FADF492F + 39B2FB98E818E088547D0080AEA073F0D51EE469D71C8140EA9CE65B5F1E8F85 + 2BC0AD8CDDD2DF67722D24252EC6290E1941ABCAEFCC1BC4EDF4EF9CC29DB194 + 06DE5A46B51BAE4F6E92A1246CAA90AB798164ADA445450388C2ACC7E995594C + 1CE0A3B884B4F8346C5AA3D01EA70779123EBDC56777E410E4ECCB61DCB7A6B6 + 3E924831162B482D9D3EF4935AF6538238EBAB0923C1D04FC484CDAEDAE78418 + 9F66F70F6D69BB73447EBEBF3CC4EE8AEF2BAE448281FF67190BEE61B4799F2D + 6B5FBE12AA4289061782A48043BB5E45676CF91D4890174CEF818EA3F368F973 + 90E5314DCCE1F5EC3C4DBC0A7E2A18F5B7BE29696C0EFF94C0B4FFCD55142AC8 + 5860457686A42E5E92E63C591A84011460CA32B39E50C5AE42B7A8C4CC0986B5 + CE21E1891C04CA8D9FB8073ACDA795F95FB2A625E719E5CD93654E077FB5DE5C + ABE3D97A8A3C67E03C2B6BA0EF5D9F0228A8E6A853ABB8CE631E18EDBD8E3E2C + 26A095C131C0DD2E6B67510A0AF808CB0A02FA919EB382551C1B76580BA0151D + B598CEB25DB8B09ED734D130D364C4F5DDAC5D072D0A2B9440C489786FBC0CB4 + 053564434810380ACC1F35153D19EF84279BF1B81351F96FDFEA907683C4944E + 310B6E880D38FAE7FC5EE90958A899A669F77A43220FCC0A8EAF0A44D4714952 + CC02CDC976D5268AC0A8E31610660BFC05A30BDF047AAA7C5225AFDBABD55EB9 + 7466EBCF406E6748D52ED5E8770FA192AE9262BA7C2B880BF3BD19EFFEE7C90B + 2F18236FC9546561B217F5BAD294860625C59EB1B5F4C066FB241111FC782439 + F5CF34C9C2296AE66920CEBF3617295B25207114E6812A0C0551F31441D219E2 + DA123A158628FBFD261A38E12EF509E6D71F289F7D03E8E6817896239223CCF5 + 96247893DB6BCF4370ED22BAE95A0FA165641F4F1BDCDF96587F9313D26A6368 + 4CB5CFB5E870A90DDFC4A5C778C35E2193ACBB4318ED6DC7C4728B632B76FC7E + F33449EBDCEE4F6E225977B079BF7ED62A14C84E2163430D0850636C8B38B241 + 8FA2D3A3DAAEE4330203C33B6C89A62A286A18CAE49C63CAD3ADA2225B917971 + DD4153648556DCBB8949CA2E93792E829B5880BED074822B5A0F5C777943C2D6 + 5D118E9012691E2D8C2347DCB008DEBABDBBC21FC4FB539B5DA678FA1E8EB6B1 + EB3422310484FD8F51C98232C10B954D8A59F097054798AF7E34435A7A061BF2 + 67929E736EE9B9FFA2CCE4086B1045A15FDCB62DA60FDE734C698BD9598E7288 + 1783B12CC12D5B6AB6C31C364E1DC0C7060CAB16E920639F3F09D6D82201A799 + 08BC1F73AB61A7998769CDCD883F208B2E1A57194F0B07F7328FEA7022924195 + 522CDA0F4036B236769973AAE469488896AA5C1D53B3FAFEA156F91096E7F5AB + 34FCBC407A84C81DB36E89BFF4B158C46AC1BCD8C3DA3E1231F7A9C11D5C4882 + D30F2FB8600F978687E38624FFE2356F79547FDFB1B4444AC773BCF6D431C151 + A2BDC8FBDB26B8C0BDBE955C3E82DCF4DF95EEE4D9552A6B79E4A537886FCEF6 + 1D8E6D98C9D1AAA04A6BC2DEE9AF33E0B9EC4EECBFCEEF9A09F420D117E3533B + C4765E22689BA80934A244E0CE6A096440E7C8C77D50B91F86DB7B7699BC2330 + 6A1E58FC1357D71050AF16CCA7FC0299466DA2E1B881F68C72E984BBC8485D45 + BDF63DC8A97E7E12543E48CF14E5D9839241DF9C5D790B568F03DC25E3A2E2EE + 0514AEFB6B6B9488FF66947A1DC310F0C8DBE5E746AA52BF35B79DFF4CB5C00C + FF9831F8613C37A5163B28968272D44C6F80DAC1F05A877EFCD1385F83CFE11C + 0C9F55A5252EFEC67EA1AC0D3AB7D273DEB5D0D740FDCD60306FC44D22AB75D5 + 573DD0587F9B2D8B00C91C6763C2170F88028D794F3E0AAA9D861C443EB774A0 + 954B8F72ADB5B1EC44192D2AE0FA9FE6BD6C4B1453BEA758017D133C94C3BDBD + 8169C8AC72BA2363E42CB918D636F73147C67F58357AD64ADBA7DD33B8C017F6 + 48589CD47CCBF6A46B10E736B52962636CD81CC9CE6DCC12A0D2ABFCA5D4BCE5 + 3C26A85182966381233FC964DC71EC7C002051C9FE5DB19F8EF746E861F044C5 + DD490935FAB7EB5F030B9C373BCBFF888CEE9AC5FE0308519999248BA197F6BC + BC26FD088852E3D5106641D8077E53FD1A6FC5C2397F33B99833C5E5870ED7F6 + 36686045EB16A49F6E5DDF50043B6EF4398CB7853ECF85E8DF673FBDE40B562E + F45CFAA48FA1429E112B7AFBB247D0BD408B8BC9CE6E1AC9392D7BB8717DB0AC + 1731F1C5CDCE463A5F5D67B24897469E212C9A89DB7CB8740BA247077333437F + FB394B2C8879EDFB19D485AF3F91F15BBB894CC23F2C576CC885EEDE5EF49425 + 51743C509BDC1A564AA3E6992456FD663749D9CFCD145DB4BCD1D3774761CA9C + F0E0D06D4261E0DF19D1B2C83F69AB56C771E70AAC6C3AEFABE95E47AB9A0448 + 4DB6CD451B0ED7BCB1980F1A65D688F9D81EA553B04F845B6FC2CEC5A3DFF4B6 + 3D70B954625F854F48456741AA4A2DA77C815B5ECA707D0352569430B8320C77 + 088CB3A7463E40E21095296BF0F5923150094BF9B1F83B3FD73E4BCC4448FE63 + 1AE4D0862D71C0F9C5AF8B4FE9253EFCF1919EAA145E9297EA96242742B8A13F + 8A9E40E2810C0EDC606DDB3F221C4856D725E028F960BDCF920E79D3194F56DD + 0E396D0A84A33796EB37926379F68879D23B53228DA4B9C75CD3DC3B0CFD21C1 + 75C7BA02876347886429F66A5C9EE4263F8017BA7257A9C8BED27E1577D6088D + 64757D2A062AF19ECCC23AB085AA0CFEC407514CFF851CF7B6CFF35F879EF1FE + 9F80A21FD32CEC418BB9949BB793CE155FB98AC622610A8DDE8FCD6EC11BC088 + 66F23328BB2F86D873D33867D9F87E00CA20FCB0AD9CF10AA170F7D9D7A0740C + CBF26199E84A4960C618671443F0E71495C5671F1D1EF8A7404A32DECC7DC60E + D38369B8CD2F49D2229071185B6156E211190344ED181992250DA267208E193D + CD5303781B5D6780CB31B8C250A71E09D65571DF6747D7FB17CDC7264661881E + 2915717EC700FF967408310A2E7ECF5F4E942CAE034706DF1007876EF880E23D + EBC041C25932FC7F4B0722B2DB5514AFFF74C048683FC85A0C8BB7DA3EDEDFED + 28D94AD13E8674A32B9CCD2AD1F12C1114AEE9F5743F033793D1C672B2BDB51A + 691D611DF2940477B14C32BED9ECAAA548E0BF58118DACB8341B7EDAEA587D77 + CBA20EF6D8E507DA2F7E7A04002ED63A371AF063699AD455DB9A01F3D566BAF7 + 93BCE9E75FCBABFFAE07BB45835E849EA8FD620677F53B27AD5AD5568371A966 + 9D2CF71E653DC35298B662ABA6B5F494E16A35CFE10C5BBDD2C8BA912BE79686 + C2A251C9A8E3CD63B01A0230E7772A37E41AB10DDE2D18EEA31B440BE5E4798B + 8BF9281844B554677536336247D3E348AB2F45F2247F11E28940183C62705C73 + F2A7B1AACE491EF1A5A70AA1DD6FAD7D92F36C26642C001AE5A3202A17034518 + 8564B8B9746D83AB2F0717F9A74DDAF9E3D8D56760404DC94000797F699395F9 + 2AB9D181AA0197D2F7B810AF619E41D0737E76B4F25357F46E8C257E497099D4 + D341D1F6FFE81B135AF7732D264BEAC7AF6488B47A4EEBDF330870200D10C902 + B47EC5E7D5EEAD3D5898784B4A9501C6884AF6FF308F28C978A0D3A703FE5DEF + DD9FBCF318B8DB80ED534C147E1B97E2E485380A4F52A2BC9370542B3BD55B74 + CAEA183AB4CC821463CC1A75AD3BCBF213C2B240292F7222444E281C193C961C + F36370BB40B284087C8FA83FE8879CC9F4F368CE6751462520ED921EB474A446 + 82999677814429D717F4971F52984B61588CA17E463EFEA6B2039712E595EE0C + D0B448109DB004A3445EEB3A0A998137E193F83F0B0254DC990C65483D7285A1 + 252F10EDE8765F179A048D82503DFE7AE200B1A543F83CD9C02C2FE8AF4ADC3B + B1F1DC99CA0983D71527BEDA17E8DDB987708DA764144BA2EC72D046E14D2E44 + E86C03D673F1FF93F452CB3FAB32C325171F20DAA85056E9DCE952E26EDFB012 + E8AA09F0D4818FA5CC95BFC6774AB4BEFB14D2C18BAA7EAC06D25868B60E246B + 85BBDDA06F38732815F831409288E737AF067E4B8845CB1D4213F05C6581A8FA + 8838B77BEBB790A33318EBC3400BE177753B25B7833A8A884A268231853AEF20 + 2EE47B9A9EA24E62E3A4FE61DAF0956C91380CD60F74A242EB30E41691A7E9AD + A0B0613D61A880DF9454562C675C47815AC3071001E888A4ABFCEF8FD3026A94 + B2DC032BFEFE0D3618D882F5460726FAAF985BC74BB43327E9C24AFC82243C7C + 1B18087B8A0CE01740BB30564C7B4538BB32B4E56CBA26EE58D874C64A038412 + 243AB4FDB8BFF2A46D7E3195C67F892F059AC2F2EBE1D8995B4DAE8129E1C8C7 + 22133925A448DA609460FDF19F7A4B861BEA8FD6274E5A0EA30E711EE503B5BB + 6BEA557DD3D5DE8E3D3A17AAEC67019101B5B88038FFC34271CF3D9DAD8F4158 + 4903798D793A68C5DF4F5099955DC85A83F0456ADFB91FC3C638797E6204F548 + EF368BFC76320B5166B2B232E76A3EE6A101065F914032BBCE0BCA2ACB8A8371 + 9881F4987187F1C17683C78178151DE852F13ECC24C64D67DF3838D78B581766 + E6C7D622E54A6B4E1A08ABD13F462FFCADABEC03B42711FBF8053441DE9BECE9 + 9E85D6BB4E4ED3740E29E649A49B80D56510B60D53ED0CE0F022E65853DFF4FC + 98FF8CD9DA199553CB5216FFB04F00D416A332DD45A588A569A7CA6B945B32BB + 45E8083BD8D617D1946BE1C09E1357904E5876D90377BABA9C48D93D4D5295E5 + 8CB6642B79E98067CF5C859C82FD7AF49EEC3159EBD645893CA2E858DE20AC7B + 6DD97602B55DD7B13CD6D69D48A63A39E8B70DD00BF7A653B0F5CD44556D7CB1 + 2FE0E4E27300C48CDA3F63E6D69EA69AFB3425A7B40394917294636D924CAC3C + 06D138A2A317E51EFE5CC8D2FD13E0DF19D0399A24389F40E51CC1DFEC55A3E5 + 7B0D7F3DF4E2994C1B371173EEECAD91655C10C12EFC01C04A71A1B8369F80F3 + A515E433B32818B5AC87A96BD9D682D3155F065365C2677BC36C8BE5A8E6A0BF + 17BD591301B901F56AE458862AC1E766510598C85D21E2C48D28AE7EBFD81F8B + F368D23B8CF8CE78F69862712A4D3124E63866C3BC0A515A0798E11F565DA04D + 300475BC4DE9A8B33CCA401A6FC945603BA3B0325DB485C4CDE8B873B6C8C7D5 + 9373C04BFC8874A058B23A770F913B237404727BF762D46942DD29419D4DC755 + 77A2F7437E203E077EF4E0C10033D7C9F7AE29D10AFB6368132B27A5F4ED3A09 + AB0AE7BD12597A034116805D0301CF04F70072C6BEFDDCAA9228AF2CD5289094 + 9EB2EEA92964F3D6FB2403A6B28F113A063E52EC8D2EBA42064E9F6C5AAF69D2 + EC50C28805B5DCD129A04A97F97743A2C14719CBD67DA6B989FFC2E1C50579C6 + FAF3767DB4328971D343F15F3CF66DC71E7A63AB070641C8CA22ACC847BF9319 + FCE13D7870E34C1C7BE7464EF2ADBB09D681B731EB29B9DD9DF4FA018DDBA5D3 + 01C2A570E19278E6C44096DC818666707A553F89608B53171F093D1553BB309A + 559AB2AE6F9F0A8FFB96E1588525EFCF79870E99EEBEB3708EC2567543F65FD7 + DC3C042709F5D8905FECF49209544CCC8FA8E71CCA866849E2B12F557DA7F6A5 + 00D7C254F4C31DF8EF8E208CE4DE2E0E967E81D4B7FD9CBE555AE039134295CE + 00E888244605E626C960B6E809156792BD05A78AE9EA62BEB5E8284B9B9D3BEC + 955B9AB892616A7E04F3D8742312EF70AEC9ADFAF29F05D815AA51947FDB4F2F + 221D21AFCFE44A04D1430CB907FB945A0EE3180A853C74E74270BED4E9DBE4F8 + B54B4E5DD1042980BA7F4C73232D3BB121FA51EEC202C1AE06D7360F32FB1A74 + 6609D8EFDBACCFDDEC2B4D3E1212392B07CDF63765CD5F83C957838702B440B7 + 5F5050298906BCA72683D26010A8596A242D4472600BA55BC9D83E6B038DF796 + F4F56C60A1AC62D2C80F87E5603030B5CE3A1AE6E994A2125A3A7D78B449F853 + E71552B2A85329F2A3327BC2456BA1EDC0C3910B2E5C2653EE9DF991E92569D5 + A29B24F99AABBF700EAE15E2C1E5E5DC545A254855927E704A72CFC80A6C1E88 + F7106ADF3EA9B990A3D97F9EA768F2782D375CF789B8A1DB448CF9486340C882 + 7EE3F92E1A706122DBF37800064400DEBEFC7731F1115270AFFA38F1D2763E4D + 78E36349EA486EA049DF565AC0794EE5B46FD533E5A59009FD94BDC229B56A8F + 404676EC9EA6C862C24220AC27AB4E18452892B914FE3A27DA0283248DDAA067 + 66CF74433F5C8DC0323918BF45B400DA594709AECBDFDA9FE1B55513984DF5FA + A5DB0AF95AC692561978D95DE7785AD9E0BFF1CF91F8BE59E62BCF63EE6A41DA + B2FE11AD6994F04E3C6D4A31A08F55AAF284BDBAFBF8895448FC65A293039303 + 3B2EE9D8A999972A4634CFCF1ED250E83B85C4C12AC51ED6664EF6541B78593B + ADCB3E415B55519BEBE1323E5544C19A41E5B526D3F95375154A605A4B7800D9 + 0E50A973E41D67DC5E93A7B4920B697CCFBE0BF469B52D61E0CD39BADA9B2BB8 + 48B9171CE867354B605FBB99E212F023C0B61980FE6F8C9237CA0058C6F7CF78 + 616058D06678A6324DBC9FFEF4C893A0F0D428ADAD5DDD464BF32E0420DDF0D5 + C2D8056BC9BE99914004273814B9191B5868E2AD0BD8FEDFC6118FAE9C437C25 + 170E6CC6E85F251629954BE9D1F71B62308B350C8B8E75DB4A3ED9731042C02B + E07CB301A04D23AF085F34CF20ACCBB47CDA54A59A9BDF6440C3F4266545FC72 + B7A939D85511DF9D38F27F7F6193F0890B317A1D8301BA29449F7F5FBE05E3F0 + 3C83B8CE28693415161285E85DDC2F1E0DB20795DA799638606D9982A134A168 + 7390B759EDC7536AFC81CEBAF7A12C2EF1A403674F2108770A1FF3B484597F90 + 60AFB66D302BA2BC160DB2AA1C611BE1B934E359BD5A686257A6C1CD864B3A5A + 3F3602B2259D84FFC32B3410BC31226E0F426957F271D52CC57494D827247F65 + 784D84AB7C780E4C07C21FF68DFBB98CC7B285A39B13386DE9C319E4A5593BD2 + 8E58F206B5EAE5C57278907AA3D29CABA694D88E055CA7732D9BFE252AB82EA4 + 52F837F614FE513FB053A48A55921C604472987299F83DB6FB88CDAC12731D32 + 76BF8E1C1F134B536427AF09E2B71A32A9D5147587645D87B84EA7E277EB43FD + 03B0B292DD5982322B81B9467434F572C81F7135A6120D96D405B845EB29E834 + D8A1C39FBA22D3BFB9CA4341ABE3E2D0D4F20079F9BADE0CEDD6525AF8D6EDB7 + 490B0D5A23C94074F265509CE266FD33516ACEC69D944A2434407BE0DF4B735B + 31E66F7FA1066DB2728B7512E196B467C2CC96C727E159F9898A0442E39480E3 + E4BDD1EB147CD8D1ACB265208B3F3656EB54D19F0E1E5B28F090C8D17887B3B1 + 4ACF67280B0DB3B45FAC1069583F6D9076F222A1E54E2A84055F6571AE91549A + 90BDBC4138CEB68B83064E71EF33A525CF9D445DABDC289736767209718F68AF + 949F53A86B020652006ABA9ABB413BFD464DE87B1E02E1706E770E051ABC56E7 + F8561AC2AA86887677D12CF1592788B2A813514134FA6C5AEDCCB75DC459619E + 0F7D6DD6BB6383A01E4D752794D1B69E1E3BEE0AF327F82C41024A32A0D9D62B + BCC7CE8B5C687CFF0E6C1920E200FD1403F144A75D66C265999B711BEC826F40 + 8194724B83D8E24E5EAB031BA6D6B71B2AC1D5151FE763FE5F6204ABB5BF935D + B0E4839357712F92B1A35C09494E5F02CD3D6C13D8977BCD6B6376DADA53B9C4 + 9A38562627AB2CDF6A17D695493DF8DBF304509D9D1D068CB083FA7DB07FB582 + 5FB43F222EA57647822F3C7472B11D1C95693A14A88B1AD67D25E6837FDF117B + 5388F78E4ACA9E3F6EA5F8043D84F960320F423661E6A0C4E673F8222E668084 + D01D1B713381B914C9F39FFE0D05388DEA7E8CFC5C4C398F2CDE70F9365B8CEF + A7240218AF972CFC4C7DFC2F31B1DF28ED6B90E4ED4A57F4416B71640679FD4B + AFCCB543E81BC544A394A921591D042E440B69102A725157F84E629DA4BFEE96 + 51A9DB5FFD5D3D66E75ADBF8880D2A7FA8613460BA4BAC497DBDF32906CC0ABF + B77C25614DBF8C75E5178B1E373E1BE91573A41E78A331234EC6B33EC23F3969 + EBA62F86FE49ACE0C814BD0CA756F4E9A01C7EB179BFBEE271407EB7DC55C658 + 0E92D6CBE48EDF64AB756213E05199B2DCC8C6B21DFC0489DF3FAD2705F502F9 + 49317D3FB4F567301782C907D8B1D1F01CD0D7F418430ADAD03D3F3264DA88C1 + 2E801C67520C5D9CCBDCC5D73B20775445C962055230A9B254E12D665B8BA1F9 + 1F369D536EE5D294280185B5665D2A96FB724E389E01EE6EF5808541E0C72EA2 + DE561C563218C39D700E6BA3024EC2D52E36E02407E5B91FF99A18BD26D40272 + FAD95DE16F8D98B1466D63B3DAF4D764928062E84CC74CE02D0A9EF3F8B7E534 + 39BE6FA95F127EB03A378D5F4E69F25C4D27372127743446C6D9363EE54FB592 + 3DC3B751950723615228A7D2696DB69F49685D81301E4BF154DD10A408F91AF1 + 9F6331106BE3F702F95B2CA4D5204DBF87823001A3D8A082FCF058EF05C8CB69 + EBE3E4886EDE0B23B705C0E7FDFAEBD1D53EE53325F66BF3465D46DA4AF27C82 + 82379F35D35CB381386CF88A9B20C953A767887BA9F268F0CE27F8867697CCA2 + 25B35A999F9DBAC54AE3219C0593BFD95A99DA247D3F6E1CADF4CF17926837E8 + 38C88234B4596894DF8E54FBBBA1E80B15E64D39EE0645F8D6C3F01912826187 + 5D25B9B6D3E6973F501B92D3F672B1DA576592C413B93872CC66C3522C4B02E8 + 2F0E9DDCE10F67C486FEBB562A8932987E8B8F2CB69BEB8EA16FEAFF79618C28 + B3A8EDF971486BEA4EC469FE945731914516E895DFABAFBE210F02C8681CF58C + 89E68C875A427D0F097154D37ED589A4B5CBA62D4155A6F61729DA6C19DFA12C + AD14D41668D16C2847CF9D10111CFF7556523919AA9453B3D1017E9A9676976B + 0B01DE60FA78D7A7FB388CDAE05C68D7447CAB09B3F56E2F89CCD79C64E5B9F6 + CDC77339DA03466C916EB3075E32EE401E781FE9BA05695881DDFA3BC2950535 + 66E0B3EA12CEE190F17A256B84702B40D7B73C133EF9CF6C0936638BF3B799F4 + BFD9A2E8A80E7F5B2B8E73E4E99C2673F3AC5E96A0C2F7D7827EDFFDF51D38D1 + EC0A6A2EA3FC4894098E1BAB281BA10618196A2164978ACC5F09B9E06F44FCB2 + 0BD1036BDBF3365FBCFA0D360C3A605507815762BE9DBDFE5C79217085C3656A + 7DFEC9BE0BCB3262477F6D3BA6F86A93FC11292C103AA1A9544F0FDB73A3AB5D + 21B102FD8690B0B50EE78F1170B4D4F87AB4A493EF61EAC20631560DB1CBB908 + 5D9151E428BB958C26D0E40AD53A90EE5722EE2929DC6E1DDFCEB6B0095CAEFB + 60BD9857A789D69A7A783E450B3FEA5B8